/home/lnzliplg/.cagefs/tmp/phpbUbGxR
.TH PHP-FPM 8 "2009" "The PHP Group" "Scripting Language"
.SH NAME
.TP 15
php-fpm \- PHP FastCGI Process Manager 'PHP-FPM'
.SH SYNOPSIS
.B php-fpm
[options]
.LP
.SH DESCRIPTION
\fBPHP\fP is a widely\-used general\-purpose scripting language that is especially suited for
Web development and can be embedded into HTML. This is a variant of PHP that will run in the background as a daemon, listening for CGI requests. Output is logged to /var/log/php-fpm.log.
.LP
Most options are set in the configuration file. The configuration file is /opt/alt/php54/etc/php-fpm.conf. By default, php-fpm will respond to CGI requests listening on localhost http port 9000. Therefore php-fpm expects your webserver to forward all requests for '.php' files to port 9000 and you should edit your webserver configuration file appropriately.
.SH OPTIONS
.TP 15
.B \-C
Do not chdir to the script's directory
.TP
.PD 0
.B \-\-php\-ini \fIpath\fP|\fIfile\fP
.TP
.PD 1
.B \-c \fIpath\fP|\fIfile\fP
Look for
.B php.ini
file in the directory
.IR path
or use the specified
.IR file
.TP
.PD 0
.B \-\-no\-php\-ini
.TP
.PD 1
.B \-n
No
.B php.ini
file will be used
.TP
.PD 0
.B \-\-define \fIfoo\fP[=\fIbar\fP]
.TP
.PD 1
.B \-d \fIfoo\fP[=\fIbar\fP]
Define INI entry
.IR foo
with value
.IR bar
.TP
.B \-e
Generate extended information for debugger/profiler
.TP
.PD 0
.B \-\-help
.TP
.PD 1
.B \-h
This help
.TP
.PD 0
.B \-\-info
.TP
.PD 1
.B \-i
PHP information and configuration
.TP
.PD 0
.B \-\-modules
.TP
.PD 1
.B \-m
Show compiled in modules
.TP
.PD 0
.B \-\-version
.TP
.PD 1
.B \-v
Version number
.B \-\-prefix \fIpath\fP
.TP
.PD 1
.B \-p
Specify alternative prefix path (the default is /opt/alt/php54)
.TP
.PD 0
.B \-\-fpm\-config \fIfile\fP
.TP
.PD 1
.B \-y
Specify alternative path to FastCGI process manager configuration file (the default is /opt/alt/php54/etc/php-fpm.conf)
.TP
.PD 0
.B \-\-test
.TP
.PD 1
.B \-t
Test FPM configuration file and exit
If called twice (\-tt), the configuration is dumped before exiting.
.TP
.PD 0
.B \-\-daemonize
.TP
.PD 1
.B \-D
Force to run in background and ignore daemonize option from configuration file.
.TP
.PD 0
.B \-\-nodaemonize
.TP
.PD 1
.B \-F
Force to stay in foreground and ignore daemonize option from configuration file.
.TP
.PD 0
.B \-\-zend\-extension \fIfile\fP
.TP
.PD 1
.B \-z \fIfile\fP
Load Zend extension
.IR file
.SH FILES
.TP 15
.B php-fpm.conf
The configuration file for the php-fpm daemon.
.TP
.B php.ini
The standard php configuration file.
.SH EXAMPLES
For any unix systems which use init.d for their main process manager, you should use the init script provided to start and stop the php-fpm daemon.
.P
.PD 1
.RS
sudo /etc/init.d/php-fpm start
.RE
.TP
For any unix systems which use systemd for their main process manager, you should use the unit file provided to start and stop the php-fpm daemon.
.P
.PD 1
.RS
sudo systemctl start php-fpm.service
.RE
.TP
If your installation has no appropriate init script, launch php-fpm with no arguments. It will launch as a daemon (background process) by default. The file /var/run/php-fpm.pid determines whether php-fpm is already up and running. Once started, php-fpm then responds to several POSIX signals:
.P
.PD 0
.RS
.B SIGINT,SIGTERM \fPimmediate termination
.TP
.B SIGQUIT \fPgraceful stop
.TP
.B SIGUSR1 \fPre-open log file
.TP
.B SIGUSR2 \fPgraceful reload of all workers + reload of fpm conf/binary
.RE
.PD 1
.P
.SH TIPS
The PHP-FPM CGI daemon will work well with most popular webservers, including Apache2, lighttpd and nginx.
.PD 1
.P
.SH SEE ALSO
The PHP-FPM website:
.PD 0
.P
.B http://php-fpm.org
.PD 1
.P
For a more or less complete description of PHP look here:
.PD 0
.P
.B http://www.php.net/manual/
.PD 1
.P
A nice introduction to PHP by Stig Bakken can be found here:
.PD 0
.P
.B http://www.zend.com/zend/art/intro.php
.PD 1
.SH BUGS
You can view the list of known bugs or report any new bug you
found at:
.PD 0
.P
.B http://bugs.php.net
.PD 1
.SH AUTHORS
PHP-FPM SAPI was written by Andrei Nigmatulin. The mailing-lists are highload-php-en (English) and highload-php-ru (Russian).
.P
The PHP Group: Thies C. Arntzen, Stig Bakken, Andi Gutmans, Rasmus Lerdorf, Sam Ruby, Sascha Schumann, Zeev Suraski, Jim Winstead, Andrei Zmievski.
.P
A List of active developers can be found here:
.PD 0
.P
.B http://www.php.net/credits.php
.PD 1
.P
And last but not least PHP was developed with the help of a huge amount of
contributors all around the world.
.SH VERSION INFORMATION
This manpage describes \fBphp-fpm\fP, version 5.4.45.
.SH COPYRIGHT
Copyright \(co 1997\-2009 The PHP Group
.PD 0
.P
Copyright (c) 2007-2009, Andrei Nigmatulin
.PD 1
.LP
This source file is subject to version 3.01 of the PHP license,
that is bundled with this package in the file LICENSE, and is
available through the world-wide-web at the following url:
.PD 0
.P
.B http://www.php.net/license/3_01.txt
.PD 1
.P
If you did not receive a copy of the PHP license and are unable to
obtain it through the world-wide-web, please send a note to
.B license@php.net
so we can mail you a copy immediately.
.TH PHAR 1 "2013" "The PHP Group" "User Commands"
.SH NAME
phar, phar.phar \- PHAR (PHP archive) command line tool
.SH SYNOPSIS
.B phar
<command> [options] ...
.LP
.SH DESCRIPTION
The \fBPHAR\fP file format provides a way to put entire PHP applications into a single
file called a "phar" (PHP Archive) for easy distribution and installation.
.P
With the \fBphar\fP command you can create, update or extract PHP archives.
.P
Commands:
add compress delete extract help help-list info list meta-del
meta-get meta-set pack sign stub-get stub-set tree version
.SH add command
Add entries to a PHAR package.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.TP
.PD
.B ...
Any number of input files and directories. If -i is in
use then ONLY files and matching the given regular
expression are being packed. If -x is given then files
matching that regular expression are NOT being packed.
.P
Optional arguments:
.TP 15
.PD
.B \-a \fIalias\fP
Provide an \fIalias\fP name for the phar file.
.TP
.PD
.B \-c \fIalgo\fP
Compression algorithm (see
.SM
.B COMPRESSION
)
.TP
.PD
.B \-i \fIregex\fP
Specifies a regular expression for input files.
.TP
.PD
.B \-l \fIlevel\fP
Number of preceding subdirectories to strip from file entries
.TP
.PD
.B \-x \fIregex\fP
Regular expression for input files to exclude.
.SH compress command
Compress or uncompress all files or a selected entry.
.P
Required arguments:
.TP 15
.PD
.B \-c \fIalgo\fP
Compression algorithm (see
.SM
.B COMPRESSION
)
.TP
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.P
Optional arguments:
.TP 15
.PD
.B -e \fIentry\fP
Name of \fIentry\fP to work on (must include PHAR internal
directory name if any).
.SH delete command
Delete entry from a PHAR archive
.P
Required arguments:
.TP 15
.PD
.B \-e \fIentry\fP
Name of \fIentry\fP to work on (must include PHAR internal
directory name if any).
.TP
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.SH extract command
Extract a PHAR package to a directory.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.P
Optional arguments:
.TP 15
.PD
.B -i \fIregex\fP
Specifies a regular expression for input files.
.TP
.PD
.B -x \fIregex\fP
Regular expression for input files to exclude.
.TP
.PD
.B ...
Directory to extract to (defaults to '.').
.SH help command
This help or help for a selected command.
.P
Optional arguments:
.TP 15
.PD
.B ...
Optional command to retrieve help for.
.SH help-list command
Lists available commands.
.SH info command
Get information about a PHAR package.
.P
By using -k it is possible to return a single value.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.P
Optional arguments:
.TP 15
.PD
.B -k \fIindex\fP
Subscription \fIindex\fP to work on.
.SH list command
List contents of a PHAR archive.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.P
Optional arguments:
.TP 15
.PD
.B -i \fIregex\fP
Specifies a regular expression for input files.
.TP
.PD
.B -x \fIregex\fP
Regular expression for input files to exclude.
.SH meta-del command
Delete meta information of a PHAR entry or a PHAR package.
.P
If -k is given then the metadata is expected to be an array and the
given index is being deleted.
.P
If something was deleted the return value is 0 otherwise it is 1.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.P
Optional arguments:
.TP 15
.PD
.B -e \fIentry\fP
Name of \fIentry\fP to work on (must include PHAR internal
directory name if any).
.TP
.PD
.B -k \fIindex\fP
Subscription \fIindex\fP to work on.
.SH meta-get command
Get meta information of a PHAR entry or a PHAR package in serialized from. If
no output file is specified for meta data then stdout is being used.
You can also specify a particular index using -k. In that case the
metadata is expected to be an array and the value of the given index
is returned using echo rather than using serialize. If that index does
not exist or no meta data is present then the return value is 1.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.P
Optional arguments:
.TP 15
.PD
.B -e \fIentry\fP
Name of \fIentry\fP to work on (must include PHAR internal
directory name if any).
.TP
.PD
.B -k \fIindex\fP
Subscription \fIindex\fP to work on.
.SH meta-set command
Set meta data of a PHAR entry or a PHAR package using serialized input. If no
input file is specified for meta data then stdin is being used. You can
also specify a particular index using -k. In that case the metadata is
expected to be an array and the value of the given index is being set.
If the metadata is not present or empty a new array will be created.
If the metadata is present and a flat value then the return value is
1. Also using -k the input is been taken directly rather then being
serialized.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.TP
.PD
.B -m \fImeta\fP
Meta data to store with entry (serialized php data).
.P
Optional arguments:
.TP 15
.PD
.B -e \fIentry\fP
Name of \fIentry\fP to work on (must include PHAR internal
directory name if any).
.TP
.PD
.B -k \fIindex\fP
Subscription \fIindex\fP to work on.
.SH pack command
Pack files into a PHAR archive.
.P
When using -s <stub>, then the stub file is being excluded from the
list of input files/dirs.To create an archive that contains PEAR class
PHP_Archive then point -p argument to PHP/Archive.php.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.TP
.PD
.B ...
Any number of input files and directories. If -i is in
use then ONLY files and matching the given regular
expression are being packed. If -x is given then files
matching that regular expression are NOT being packed.
.P
Optional arguments:
.TP 15
.PD
.B \-a \fIalias\fP
Provide an \fIalias\fP name for the phar file.
.TP
.PD
.B \-b \fIbang\fP
Hash-bang line to start the archive (e.g. #!/usr/bin/php).
The hash mark itself '#!' and the newline character are optional.
.TP
.PD
.B \-c \fIalgo\fP
Compression algorithm (see
.SM
.B COMPRESSION
)
.TP
.PD
.B \-h \fIhash\fP
Selects the \fIhash\fP algorithm (see
.SM
.B HASH
)
.TP
.PD
.B \-i \fIregex\fP
Specifies a regular expression for input files.
.TP
.PD
.B \-l \fIlevel\fP
Number of preceding subdirectories to strip from file entries
.TP
.PD
.B \-p \fIloader\fP
Location of PHP_Archive class file (pear list-files
PHP_Archive).You can use '0' or '1' to locate it
automatically using the mentioned pear command. When
using '0' the command does not error out when the class
file cannot be located. This switch also adds some code
around the stub so that class PHP_Archive gets
registered as phar:// stream wrapper if necessary. And
finally this switch will add the file phar.inc from
this package and load it to ensure class Phar is
present.
.TP
.PD
.B \-s \fIstub\fP
Select the \fIstub\fP file.
.TP
.PD
.B \-x \fIregex\fP
Regular expression for input files to exclude.
.TP
.PD
.B \-y \fIkey\fP
Private \fIkey\fP for OpenSSL signing.
.SH sign command
Set signature hash algorithm.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.TP
.PD
.B \-h \fIhash\fP
Selects the \fIhash\fP algorithm (see
.SM
.B HASH
)
.P
Optional arguments:
.TP 15
.PD
.B \-y \fIkey\fP
Private \fIkey\fP for OpenSSL signing.
.SH stub-get command
Get the stub of a PHAR file. If no output file is specified as stub then stdout
is being used.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.P
Optional arguments:
.TP 15
.PD
.B \-s \fIstub\fP
Select the \fIstub\fP file.
.SH stub-set command
Set the stub of a PHAR file. If no input file is specified as stub then stdin
is being used.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.P
Optional arguments:
.TP 15
.PD
.B \-b \fIbang\fP
Hash-bang line to start the archive (e.g. #!/usr/bin/php).
The hash mark itself '#!' and the newline character are optional.
.TP
.PD
.B \-p \fIloader\fP
Location of PHP_Archive class file (pear list-files
PHP_Archive).You can use '0' or '1' to locate it
automatically using the mentioned pear command. When
using '0' the command does not error out when the class
file cannot be located. This switch also adds some code
around the stub so that class PHP_Archive gets
registered as phar:// stream wrapper if necessary. And
finally this switch will add the file phar.inc from
this package and load it to ensure class Phar is
present.
.TP
.PD
.B \-s \fIstub\fP
Select the \fIstub\fP file.
.SH tree command
Get a directory tree for a PHAR archive.
.P
Required arguments:
.TP 15
.PD
.B -f \fIfile\fP
Specifies the phar \fIfile\fP to work on.
.P
Optional arguments:
.TP 15
.PD
.B \-i \fIregex\fP
Specifies a regular expression for input files.
.TP
.PD
.B \-x \fIregex\fP
Regular expression for input files to exclude.
.SH version command
Get information about the PHAR environment and the tool version.
.SH COMPRESSION
Algorithms:
.TP 15
.PD
.B 0
No compression
.TP
.PD
.B none
No compression
.TP
.PD
.B auto
Automatically select compression algorithm
.TP
.PD
.B gz
GZip compression
.TP
.PD
.B gzip
GZip compression
.TP
.PD
.B bz2
BZip2 compression
.TP
.PD
.B bzip2
BZip2 compression
.SH HASH
Algorithms:
.TP 15
.PD
.TP
.PD
.B md5
MD5
.TP
.PD
.B sha1
SHA1
.TP
.PD
.B sha256
SHA256
.TP
.PD
.B sha512
SHA512
.TP
.PD
.B openssl
OpenSSL
.SH SEE ALSO
For a more or less complete description of PHAR look here:
.PD 0
.P
.B http://php.net/phar
.PD 1
.P
.SH BUGS
You can view the list of known bugs or report any new bug you
found at:
.PD 0
.P
.B http://bugs.php.net
.PD 1
.SH AUTHORS
The PHP Group: Thies C. Arntzen, Stig Bakken, Andi Gutmans, Rasmus Lerdorf, Sam Ruby, Sascha Schumann, Zeev Suraski, Jim Winstead, Andrei Zmievski.
.P
Work for the PHP archive was done by Gregory Beaver, Marcus Boerger.
.P
A List of active developers can be found here:
.PD 0
.P
.B http://www.php.net/credits.php
.PD 1
.P
And last but not least PHP was developed with the help of a huge amount of
contributors all around the world.
.SH VERSION INFORMATION
This manpage describes \fBphar\fP, version 5.4.45.
.SH COPYRIGHT
Copyright \(co 1997\-2014 The PHP Group
.LP
This source file is subject to version 3.01 of the PHP license,
that is bundled with this package in the file LICENSE, and is
available through the world-wide-web at the following url:
.PD 0
.P
.B http://www.php.net/license/3_01.txt
.PD 1
.P
If you did not receive a copy of the PHP license and are unable to
obtain it through the world-wide-web, please send a note to
.B license@php.net
so we can mail you a copy immediately.
.TH php\-config 1 "2010" "The PHP Group" "Scripting Language"
.SH NAME
php\-config \- get information about PHP configuration and compile options
.SH SYNOPSIS
.B php\-config
[options]
.LP
.SH DESCRIPTION
.B php\-config
is a simple shell script for obtaining information about installed PHP configuration.
.SH OPTIONS
.TP 15
.PD 0
.B \-\-prefix
Directory prefix where PHP is installed, e.g. /usr/local
.TP
.PD 0
.B \-\-includes
List of \-I options with all include files
.TP
.PD 0
.B \-\-ldflags
LD Flags which PHP was compiled with
.TP
.PD 0
.B \-\-libs
Extra libraries which PHP was compiled with
.TP
.PD 0
.B \-\-man-dir
The directory prefix where the manpages is installed
.TP
.PD 0
.B \-\-extension-dir
Directory where extensions are searched by default
.TP
.PD 0
.B \-\-include-dir
Directory prefix where header files are installed by default
.TP
.PD 0
.B \-\-php-binary
Full path to php CLI or CGI binary
.TP
.PD 0
.B \-\-php-sapis
Show all SAPI modules available
.TP
.PD 0
.B \-\-configure-options
Configure options to recreate configuration of current PHP installation
.TP
.PD 0
.B \-\-version
PHP version
.TP
.PD 0
.B \-\-vernum
PHP version as integer
.TP
.PD 1
.P
.SH SEE ALSO
.BR php (1)
.SH VERSION INFORMATION
This manpage describes \fBphp\fP, version 5.4.45.
.SH COPYRIGHT
Copyright \(co 1997\-2010 The PHP Group
.LP
This source file is subject to version 3.01 of the PHP license,
that is bundled with this package in the file LICENSE, and is
available through the world-wide-web at the following url:
.PD 0
.P
.B http://www.php.net/license/3_01.txt
.PD 1
.P
If you did not receive a copy of the PHP license and are unable to
obtain it through the world-wide-web, please send a note to
.B license@php.net
so we can mail you a copy immediately.
.so man1/php.1
.TH PHP 1 "2014" "The PHP Group" "Scripting Language"
.SH NAME
php \- PHP Command Line Interface 'CLI'
.P
php-cgi \- PHP Common Gateway Interface 'CGI' command
.SH SYNOPSIS
.B php
[options] [
.B \-f\fP ]
.IR file
[[\-\-]
.IR args.\|.\|. ]
.LP
.B php
[options]
.B \-r
.IR code
[[\-\-]
.IR args.\|.\|. ]
.LP
.B php
[options] [\-B
.IR begin_code ]
.B \-R
.IR code
[\-E
.IR end_code ]
[[\-\-]
.IR args.\|.\|. ]
.LP
.B php
[options] [\-B
.IR begin_code ]
.B \-F
.IR file
[\-E
.IR end_code ]
[[\-\-]
.IR args.\|.\|. ]
.LP
.B php
[options] \-\- [
.IR args.\|.\|. ]
.LP
\fBphp \fP[options] \fB\-a\fP
.LP
.B php
[options] \-S
.IR addr:port
[\-t
.IR docroot ]
.LP
.SH DESCRIPTION
\fBPHP\fP is a widely\-used general\-purpose scripting language that is especially suited for
Web development and can be embedded into HTML. This is the command line interface
that enables you to do the following:
.P
You can parse and execute files by using parameter \-f followed by the name of the
.IR file
to be executed.
.LP
Using parameter \-r you can directly execute PHP
.IR code
simply as you would do inside a
.B \.php
file when using the
.B eval()
function.
.LP
It is also possible to process the standard input line by line using either
the parameter \-R or \-F. In this mode each separate input line causes the
.IR code
specified by \-R or the
.IR file
specified by \-F to be executed.
You can access the input line by \fB$argn\fP. While processing the input lines
.B $argi
contains the number of the actual line being processed. Further more
the parameters \-B and \-E can be used to execute
.IR code
(see \-r) before and
after all input lines have been processed respectively. Notice that the
input is read from
.B STDIN
and therefore reading from
.B STDIN
explicitly changes the next input line or skips input lines.
.LP
PHP also contains an built-in web server for application development purpose. By using the \-S option where
.B addr:port
point to a local address and port PHP will listen to HTTP requests on that address and port and serve files from the current working directory or the
.B docroot
passed by the \-t option.
.LP
If none of \-r \-f \-B \-R \-F \-E or \-S is present but a single parameter is given
then this parameter is taken as the filename to parse and execute (same as
with \-f). If no parameter is present then the standard input is read and
executed.
.SH OPTIONS
.TP 15
.PD 0
.B \-\-interactive
.TP
.PD 1
.B \-a
Run PHP interactively. This lets you enter snippets of PHP code that directly
get executed. When readline support is enabled you can edit the lines and also
have history support.
.TP
.PD 0
.B \-\-bindpath \fIaddress:port\fP|\fIport\fP
.TP
.PD 1
.B \-b \fIaddress:port\fP|\fIport\fP
Bind Path for external FASTCGI Server mode (CGI only).
.TP
.PD 0
.B \-\-no\-chdir
.TP
.PD 1
.B \-C
Do not chdir to the script's directory (CGI only).
.TP
.PD 0
.B \-\-no\-header
.TP
.PD 1
.B \-q
Quiet-mode. Suppress HTTP header output (CGI only).
.TP
.PD 0
.B \-\-timing \fIcount\fP
.TP
.PD 1
.B \-T \fIcount\fP
Measure execution time of script repeated count times (CGI only).
.TP
.PD 0
.B \-\-php\-ini \fIpath\fP|\fIfile\fP
.TP
.PD 1
.B \-c \fIpath\fP|\fIfile\fP
Look for
.B php.ini
file in the directory
.IR path
or use the specified
.IR file
.TP
.PD 0
.B \-\-no\-php\-ini
.TP
.PD 1
.B \-n
No
.B php.ini
file will be used
.TP
.PD 0
.B \-\-define \fIfoo\fP[=\fIbar\fP]
.TP
.PD 1
.B \-d \fIfoo\fP[=\fIbar\fP]
Define INI entry
.IR foo
with value
.IR bar
.TP
.B \-e
Generate extended information for debugger/profiler
.TP
.PD 0
.B \-\-file \fIfile\fP
.TP
.PD 1
.B \-f \fIfile\fP
Parse and execute
.IR file
.TP
.PD 0
.B \-\-help
.TP
.PD 1
.B \-h
This help
.TP
.PD 0
.B \-\-hide\-args
.TP
.PD 1
.B \-H
Hide script name (\fIfile\fP) and parameters (\fIargs\.\.\.\fP) from external
tools. For example you may want to use this when a php script is started as
a daemon and the command line contains sensitive data such as passwords.
.TP
.PD 0
.B \-\-info
.TP
.PD 1
.B \-i
PHP information and configuration
.TP
.PD 0
.B \-\-syntax\-check
.TP
.PD 1
.B \-l
Syntax check only (lint)
.TP
.PD 0
.B \-\-modules
.TP
.PD 1
.B \-m
Show compiled in modules
.TP
.PD 0
.B \-\-run \fIcode\fP
.TP
.PD 1
.B \-r \fIcode\fP
Run PHP
.IR code
without using script tags
.B '<?..?>'
.TP
.PD 0
.B \-\-process\-begin \fIcode\fP
.TP
.PD 1
.B \-B \fIbegin_code\fP
Run PHP
.IR begin_code
before processing input lines
.TP
.PD 0
.B \-\-process\-code \fIcode\fP
.TP
.PD 1
.B \-R \fIcode\fP
Run PHP
.IR code
for every input line
.TP
.PD 0
.B \-\-process\-file \fIfile\fP
.TP
.PD 1
.B \-F \fIfile\fP
Parse and execute
.IR file
for every input line
.TP
.PD 0
.B \-\-process\-end \fIcode\fP
.TP
.PD 1
.B \-E \fIend_code\fP
Run PHP
.IR end_code
after processing all input lines
.TP
.PD 0
.B \-\-syntax\-highlight
.TP
.PD 1
.B \-s
Output HTML syntax highlighted source
.TP
.PD 0
.B \-\-server \fIaddr:port\fP
.TP
.PD 1
.B \-S \fIaddr:port\fP
Start built-in web server on the given local address and port
.TP
.PD 0
.B \-\-docroot \fIdocroot\fP
.TP
.PD 1
.B \-t \fIdocroot\fP
Specify the document root to be used by the built-in web server
.TP
.PD 0
.B \-\-version
.TP
.PD 1
.B \-v
Version number
.TP
.PD 0
.B \-\-strip
.TP
.PD 1
.B \-w
Output source with stripped comments and whitespace
.TP
.PD 0
.B \-\-zend\-extension \fIfile\fP
.TP
.PD 1
.B \-z \fIfile\fP
Load Zend extension
.IR file
.TP
.IR args.\|.\|.
Arguments passed to script. Use
.B '\-\-'
.IR args
when first argument starts with
.B '\-'
or script is read from stdin
.TP
.PD 0
.B \-\-rfunction
.IR name
.TP
.PD 1
.B \-\-rf
.IR name
Shows information about function
.B name
.TP
.PD 0
.B \-\-rclass
.IR name
.TP
.PD 1
.B \-\-rc
.IR name
Shows information about class
.B name
.TP
.PD 0
.B \-\-rextension
.IR name
.TP
.PD 1
.B \-\-re
.IR name
Shows information about extension
.B name
.TP
.PD 0
.B \-\-rzendextension
.IR name
.TP
.PD 1
.B \-\-rz
.IR name
Shows information about Zend extension
.B name
.TP
.PD 0
.B \-\-rextinfo
.IR name
.TP
.PD 1
.B \-\-ri
.IR name
Shows configuration for extension
.B name
.TP
.B \-\-ini
Show configuration file names
.SH FILES
.TP 15
.B php\-cli.ini
The configuration file for the CLI version of PHP.
.TP
.B php.ini
The standard configuration file will only be used when
.B php\-cli.ini
cannot be found.
.SH EXAMPLES
.TP 5
\fIphp \-r 'echo "Hello World\\n";'\fP
This command simply writes the text "Hello World" to standard out.
.TP
\fIphp \-r 'print_r(gd_info());'\fP
This shows the configuration of your gd extension. You can use this
to easily check which image formats you can use. If you have any
dynamic modules you may want to use the same ini file that php uses
when executed from your webserver. There are more extensions which
have such a function. For dba use:
.RS
\fIphp \-r 'print_r(dba_handlers(1));'\fP
.RE
.TP
\fIphp \-R 'echo strip_tags($argn)."\\n";'\fP
This PHP command strips off the HTML tags line by line and outputs the
result. To see how it works you can first look at the following PHP command
\'\fIphp \-d html_errors=1 \-i\fP\' which uses PHP to output HTML formatted
configuration information. If you then combine those two
\'\fIphp \.\.\.|php \.\.\.\fP\' you'll see what happens.
.TP
\fIphp \-E 'echo "Lines: $argi\\n";'\fP
Using this PHP command you can count the lines being input.
.TP
\fIphp \-R '@$l+=count(file($argn));' \-E 'echo "Lines:$l\\n";'\fP
In this example PHP expects each input line being a file. It counts all lines
of the files specified by each input line and shows the summarized result.
You may combine this with tools like find and change the php scriptlet.
.TP
\fIphp \-R 'echo "$argn\\n"; fgets(STDIN);'\fP
Since you have access to STDIN from within \-B \-R \-F and \-E you can skip
certain input lines with your code. But note that in such cases $argi only
counts the lines being processed by php itself. Having read this you will
guess what the above program does: skipping every second input line.
.SH TIPS
You can use a shebang line to automatically invoke php
from scripts. Only the CLI version of PHP will ignore
such a first line as shown below:
.P
.PD 0
.RS
#!/bin/php
.P
<?php
.P
// your script
.P
?>
.RE
.PD 1
.P
.SH SEE ALSO
For a more or less complete description of PHP look here:
.PD 0
.P
.B http://www.php.net/manual/
.PD 1
.P
.SH BUGS
You can view the list of known bugs or report any new bug you
found at:
.PD 0
.P
.B http://bugs.php.net
.PD 1
.SH AUTHORS
The PHP Group: Thies C. Arntzen, Stig Bakken, Andi Gutmans, Rasmus Lerdorf, Sam Ruby, Sascha Schumann, Zeev Suraski, Jim Winstead, Andrei Zmievski.
.P
Additional work for the CLI sapi was done by Edin Kadribasic, Marcus Boerger and Johannes Schlueter.
.P
A List of active developers can be found here:
.PD 0
.P
.B http://www.php.net/credits.php
.PD 1
.P
And last but not least PHP was developed with the help of a huge amount of
contributors all around the world.
.SH VERSION INFORMATION
This manpage describes \fBphp\fP, version 5.4.45.
.SH COPYRIGHT
Copyright \(co 1997\-2013 The PHP Group
.LP
This source file is subject to version 3.01 of the PHP license,
that is bundled with this package in the file LICENSE, and is
available through the world-wide-web at the following url:
.PD 0
.P
.B http://www.php.net/license/3_01.txt
.PD 1
.P
If you did not receive a copy of the PHP license and are unable to
obtain it through the world-wide-web, please send a note to
.B license@php.net
so we can mail you a copy immediately.
.so man1/phar.1
.TH phpize 1 "2010" "The PHP Group" "Scripting Language"
.SH NAME
phpize \- prepare a PHP extension for compiling
.SH SYNOPSIS
.B phpize
[options]
.LP
.SH DESCRIPTION
.B phpize
is a shell script to prepare PHP extension for compiling.
.SH OPTIONS
.TP 15
.PD 0
.B \-\-clean
Remove all created files
.TP
.PD 0
.B \-\-help
Prints usage information
.TP
.PD 0
.B \-\-version
.TP
.PD 1
.B \-v
Prints API version information
.TP
.PD 1
.P
.SH SEE ALSO
.BR php (1)
.SH VERSION INFORMATION
This manpage describes \fBphp\fP, version 5.4.45.
.SH COPYRIGHT
Copyright \(co 1997\-2010 The PHP Group
.LP
This source file is subject to version 3.01 of the PHP license,
that is bundled with this package in the file LICENSE, and is
available through the world-wide-web at the following url:
.PD 0
.P
.B http://www.php.net/license/3_01.txt
.PD 1
.P
If you did not receive a copy of the PHP license and are unable to
obtain it through the world-wide-web, please send a note to
.B license@php.net
so we can mail you a copy immediately.
ionCube Loader 15.0 User Guide
=====================================
This document describes the available php.ini configuration options of the
ionCube Loader that relate to processing of PHP encoded files, and also the
ionCube24 service. It also describes which encoded files can be run by each
ionCube Loader.
PERFORMANCE OF ENCODED FILES
----------------------------
We recommend that the encoded paths feature (see below) is used
with encoded files in order to maximise performance.
ENCODED FILES
-------------
INI entry: ioncube.loader.encoded_paths
Purpose: Specify the locations of encoded files
The ionCube Loader will normally examine a PHP file before processing
to test whether it is encoded, and will run the file itself if necessary.
Although this checking is very efficient, restricting which files the
Loader tests for being encoded may give extra performance. If set to
a series of paths or files, only files in those locations are tested.
Entries should be separated by a : on Unix and ; on Windows.
A path may be prefixed with + or - to add or remove that path from
the possible locations. + is assumed if no character is given.
Examples: (... means ioncube.loader.encoded_paths)
* Site with a single encoded module in /var/www/html/modules/RSS
... = "/var/www/html/modules/RSS"
* As above, with a site configuration file encoded too.
... = "/var/www/html/modules/RSS:/var/www/html/config/config.php"
* Encoded files may be anywhere except for /var/www/html/framework
... = "/:-/var/www/html/framework"
* Site with most modules encoded except for one
... = "/var/www/html/modules:-/var/www/html/modules/plain"
* As above, with an encoded config file in the plain directory
... = "/site/modules:-/site/modules/plain:/site/modules/plain/config.php"
Locations:
The ioncube.loader.encoded_paths property can be set in a php.ini
file, in a .htaccess file (when using Apache), in a .user.ini file
(when using CGI PHP 5.3+) or using ini_set within a PHP script. In ini
files only the last value will be used for the encoded_paths property. If
you wish to build up the value in several lines then, for PHP 5.1+, you
can use the following syntax:
ioncube.loader.encoded_paths = "/path1"
ioncube.loader.encoded_paths = ${ioncube.loader.encoded_paths}":/path2"
; etc...
LIMITATIONS OF LOADERS AND ENCODED FILES
----------------------------------------
Encoded files can, in general, run on versions of PHP equal to
or greater than the source language of the Encoder used to
produce them. So a file produced by the Encoder for PHP 7.2
can be run by the Loaders for PHP 7.2, 7.3 and 7.4, but 7.1. This
means that the Loaders offer good backwards compatibility,
however there are the following limitations:
* The Loader for PHP 8.4 can run files produced by the PHP 8.2, 8.3
and 8.4 Encoders.
* The Loader for PHP 8.3 can run files produced by the PHP 8.2 and
8.3 Encoders.
* The Loader for PHP 8.2 can only run files produced for
PHP 8.2. Updates for files produced for PHP 8.1 should
be obtained to use them with PHP 8.2.
* The Loader for PHP 8.1 can only run files produced for
PHP 8.1.
* The Loaders for PHP 7.1 through 7.4 can only run files
produced by the Encoders for PHP 7.
* The Loader for PHP 7.0 can only run files produced by the
Encoder for PHP 5.6.
* The Loaders for PHP 5.5 and PHP 5.6 cannot run files
produced by the PHP 4 Encoder.
IONCUBE24 : real-time intrusion protection and PHP error reporting
---------
### (Available for Linux 32 and 64 bit x86 servers using PHP 7)
ionCube24 (https://ioncube24.com) is an ionCube service that uses the
ionCube Loader to provide both real-time protection against the exploit of
website vulnerabilities and alerting of website errors.
Vulnerabilities in PHP applications are common, particularly in sites using
Wordpress and other plugin based systems. Exploits result in website
defacement or customer data being compromised, and ionCube24 provides a
uniquely powerful defense.
PHP errors can cause intermittent or even persistent blank pages or errors for
visitors until discovered, and without active monitoring this could go
undetected indefinitely. ionCube24 active monitoring ensures you are always
aware of problems in your website code.
ionCube24 is free to try, with the server side support built into the Linux
Loaders as standard. With the Loader installed, ionCube24 can be activated
at any time to give active intrusion protection and error reporting.
## php.ini settings
ionCube24 has a powerful real-time web interface to configure, monitor and
manage things, and there are also settings that can be used in a php.ini
file as summarised below.
The setup process at https://ioncube24.com automatically gives the settings
that you need to get started, but you may wish to make changes yourself
once setup. The default values are given with each example.
### Global settings
INI entry: ic24.enable ; default 0
Purpose: Enable or disable all ionCube24 features.
This defaults to 0 (off), and in this case no ionCube24 behaviour is
activated.
Example:
ic24.enable = 1
----------
INI entry: ic24.api_access_key ; provided during setup
Purpose: An authentication key for adminstration requests.
This value is provided when adding a server to ionCube24.
----------
INI entry: ic24.api_check_ip ; default 1
Purpose: Specify whether the IP for admin requests should be validated
If set, ionCube24 refuses access to API functions unless the calling IP
is a known ionCube IP address. This option should be left with the
default setting unless web requests pass through a proxy and your site
appears to be accessed from the IP of the proxy instead of ionCube. Note
that access to API functions will still be authenticated by access key.
----------
INI entry: ic24.api_max_timeout ; default 7
Purpose: Maximum timeout period when sending notifications to ionCube24.
The actual period is adaptive so that a brief increase in typical latency
will favour a timeout followed by a retry rather than a longer than usual
timeout.
----------
INI entry: ic24.home_dir ; no default
Purpose: The home directory for ionCube24 related system files.
A location outside of the web root is recommended. It should be writable
by the web server during startup.
Example:
ic24.home_dir = /var/www/ic24_home
----------
INI entry: ic24.update_domains_retry_interval ; default 30
Purpose: The number of seconds to wait before retrying a fetch of the set
of domains being managed.
### Security related settings
INI entry: ic24.sec.enable ; default "auto"
Purpose: Enable the intrusion protection feature of ionCube24.
Accepted values:
* "auto" (default) - allow setting from the ionCube24 control panel.
* 1 : always enabled.
* 0 : disabled.
----------
INI entry: ic24.sec.initial_state ; default 1
Purpose: The default for whether security should be enabled or
disabled. The default is to enable protection. Any files on a protected
domain will become blocked if they are changed, so setting this to 0 will
avoid accidental blocking when using ionCube24 for the first time.
Protection may be enabled and disabled using the ionCube24 control panel and
also via the User API.
Accepted values:
* 1 : protection will be active when ionCube24 initialises.
* 0 : protection will be disabled.
----------
INI entry: ic24.sec.initial_action ; default "block"
Purpose: The initial setting for how new and modified files should be
treated when about to execute. The default is to block. The action is taken
only if protection is enabled, and the setting may be changed via the
ionCube24 control panel.
Accepted values:
* "block" : prevent execution of new or modified files
* "allow" : allow execution of new or modified files
Note that depending on the notification settings, a notification may still
be generated when a new or modified file is about to execute even if it is
not blocked.
----------
INI entry: ic24.sec.initial_notify ; default "always"
Purpose: The initial setting for whether a notification is generated the
first time an unacknowledged new or modified file is attempted to be
executed. This setting can be changed via the ionCube24 control panel.
Accepted values:
* "always" : always notify of a new modification
* "once" : only the first detected modification is reported
* "never" : never notify of new and modified files
----------
INI entry: ic24.sec.exclusion_key ; provided during setup
Purpose: A key that if present at the start of a file, will identify the
file as trusted. This value is provided when adding a server to ionCube24.
----------
INI entry: ic24.sec.trusted_include_paths ; no default
Purpose: List paths from where files can be included and automatically
trusted.
Example:
ic24.sec.trusted_include_paths = "/var/cache:/var/cache2"
Directories can be excluded from the list by prefixing with a minus
character -. e.g.
"/var/cache:-/var/cache/subdir"
This is useful if your site creates and/or modifies files by itself from
time to time, e.g. in a cache directory. Requests that *directly* access
files on a trusted include path will be blocked but the file itself will
not be blocked, so requests that use the file as intended will still work.
See ioncube24.com for more details once signed up. As an alternative, if
possible we recommend producing files that include the exclusion key.
----------
INI entry: ic24.sec.block_uploaded_files ; default 1
Purpose: If set, block any uploaded files in ionCube24 that are processed
using the standard PHP mechanism for uploaded files. This applies even if
the file is subsequently included and where included files being
automatically approved with the previous setting.
----------
INI entry: ic24.sec.block_stdin ; default 1
Purpose: Refuse code that PHP sees via stdin. If disabled, code via
stdin will run without security checking as there is no filepath. This
setting should be left on as PHP would normally never receive a script via
stdin.
### PHP Error reporting settings
INI entry: ic24.phperr.enable ; default "auto"
Purpose: Enable reporting of PHP errors to ionCube24. When enabled, any
non-ignored errors are reported to ionCube24 in realtime, triggering
alerting so errors can be investigated as necessary.
Accepted values:
* "auto" (default) - allow setting from the ionCube24 control panel.
* 1 : always enabled.
* 0 : disabled.
----------
### Deprecated settings
Deprecated settings are subject to removal in a future
release.
INI entry: ic24.phperr.ignore ; default 0
Purpose: Specify default error levels to always ignore for all domains.
Note that default and per-domain errors to ignore can also be set via the
web interface, and are combined with this setting. Leaving this unset and
using the web interface is recommended for maximum flexibility.
Example:
ic24.phperr.ignore = E_NOTICE | E_DEPRECATED
(c) ionCube Ltd. 2025
<?php // -*- c++ -*-
/**
* ionCube Loader install Wizard
*
* ionCube is a registered trademark of ionCube Ltd.
*
* Copyright (c) ionCube Ltd. 2002-2022
*/
define ('ERROR_UNKNOWN_OS',1);
define ('ERROR_UNSUPPORTED_OS',2);
define ('ERROR_UNKNOWN_ARCH',3);
define ('ERROR_UNSUPPORTED_ARCH',4);
define ('ERROR_UNSUPPORTED_ARCH_OS',5);
define ('ERROR_WINDOWS_64_BIT',6);
define ('ERROR_PHP_UNSUPPORTED',7);
define ('ERROR_PHP_DEBUG_BUILD',8);
define ('ERROR_RUNTIME_EXT_DIR_NOT_FOUND',101);
define ('ERROR_RUNTIME_LOADER_FILE_NOT_FOUND',102);
define ('ERROR_INI_NOT_FIRST_ZE',201);
define ('ERROR_INI_WRONG_ZE_START',202);
define ('ERROR_INI_ZE_LINE_NOT_FOUND',203);
define ('ERROR_INI_LOADER_FILE_NOT_FOUND',204);
define ('ERROR_INI_NOT_FULL_PATH',205);
define ('ERROR_INI_NO_PATH',206);
define ('ERROR_INI_NOT_FOUND',207);
define ('ERROR_INI_NOT_READABLE',208);
define ('ERROR_INI_MULTIPLE_IC_LOADER_LINES',209);
define ('ERROR_INI_USER_INI_NOT_FOUND',210);
define ('ERROR_INI_USER_CANNOT_CREATE',211);
define ('ERROR_LOADER_UNEXPECTED_NAME',301);
define ('ERROR_LOADER_NOT_READABLE',302);
define ('ERROR_LOADER_PHP_MISMATCH',303);
define ('ERROR_LOADER_NONTS_PHP_TS',304);
define ('ERROR_LOADER_TS_PHP_NONTS',305);
define ('ERROR_LOADER_WRONG_OS',306);
define ('ERROR_LOADER_WRONG_ARCH',307);
define ('ERROR_LOADER_WRONG_GENERAL',308);
define ('ERROR_LOADER_WIN_SERVER_NONWIN',321);
define ('ERROR_LOADER_WIN_NONTS_PHP_TS',322);
define ('ERROR_LOADER_WIN_TS_PHP_NONTS',323);
define ('ERROR_LOADER_WIN_PHP_MISMATCH',324);
define ('ERROR_LOADER_WIN_COMPILER_MISMATCH',325);
define ('ERROR_LOADER_NOT_FOUND',380);
define ('ERROR_LOADER_PHP_VERSION_UNKNOWN',390);
define ('SERVER_UNKNOWN',0);
define ('HAS_PHP_INI',1);
define ('SERVER_SHARED',2);
define ('SERVER_VPS',5);
define ('SERVER_DEDICATED',7);
define ('SERVER_LOCAL',9);
define ('IONCUBE_IP_ADDRESS',
'94.101.154.134');
define ('IONCUBE_ACCESS_ADDRESS',
'lwaccess.ioncube.com');
define ('LOADERS_PAGE',
'https://loaders.ioncube.com/');
define ('SUPPORT_SITE',
'https://support.ioncube.com/');
define ('WIZARD_SUPPORT_TICKET_DEPARTMENT',
'3');
define ('LOADER_FORUM_URL',
'https://forum.ioncube.com/viewforum.php?f=4');
define ('LOADERS_FAQ_URL',
'https://www.ioncube.com/faqs/loaders.php');
define ('UNIX_ERRORS_URL',
'https://www.ioncube.com/loaders/unix_startup_errors.php');
define ('LOADER_WIZARD_URL',
LOADERS_PAGE);
define ('ENCODER_URL',
'https://www.ioncube.com/sa_encoder.php');
define ('LOADER_VERSION_URL',
'https://www.ioncube.com/feeds/product_info/versions.php');
define ('WIZARD_LATEST_VERSION_URL',
LOADER_VERSION_URL . '?item=loader-wizard');
define ('PHP_COMPILERS_URL',
LOADER_VERSION_URL . '?item=php-compilers');
define ('LOADER_PLATFORM_URL',
LOADER_VERSION_URL . '?item=loader-platforms-all');
define ('LOADER_LATEST_VERSIONS_URL',
LOADER_VERSION_URL . '?item=loader-versions');
define ('LOADER_PHP_VERSION_URL',
LOADER_VERSION_URL . '?item=loader-php-support');
define ('WIZARD_STATS_URL',
'https://www.ioncube.com/feeds/stats/wizard.php');
define ('IONCUBE_DOWNLOADS_SERVER',
'https://downloads.ioncube.com/loader_downloads');
define ('IONCUBE24_URL',
'https://ioncube24.com');
define ('IONCUBE_CONNECT_TIMEOUT',4);
define ('DEFAULT_SELF','/ioncube/loader-wizard.php');
define ('LOADER_NAME_CHECK',true);
define ('LOADER_EXTENSION_NAME','ionCube Loader');
define ('LOADER_SUBDIR','ioncube');
define ('WINDOWS_IIS_LOADER_DIR', 'system32');
define ('ADDITIONAL_INI_FILE_NAME','00-ioncube.ini');
define ('UNIX_SYSTEM_LOADER_DIR','/usr/local/ioncube');
define ('RECENT_LOADER_VERSION','4.0.7');
define ('LATEST_LOADER_MAJOR_VERSION',12);
define ('LOADERS_PACKAGE_PREFIX','ioncube_loaders_');
define ('SESSION_LIFETIME_MINUTES',360);
define ('WIZARD_EXPIRY_MINUTES',2880);
define ('IONCUBE_WIZARD_EXPIRY_MINUTES',10080);
define ('MIN_INITIALISE_TIME',4);
define ('IC24_ENABLED_INI_PROPERTY',"ic24.enable");
run();
function php4_http_build_query($formdata, $numeric_prefix = null, $key = null ) {
$res = array();
foreach ((array)$formdata as $k=>$v) {
$tmp_key = urlencode(is_int($k) ? $numeric_prefix.$k : $k);
if ($key) $tmp_key = $key.'['.$tmp_key.']';
if ( is_array($v) || is_object($v) ) {
$res[] = php4_http_build_query($v, null , $tmp_key);
} else {
$res[] = $tmp_key."=".urlencode($v);
}
}
$separator = ini_get('arg_separator.output');
return implode($separator, $res);
}
function script_version()
{
return "2.74";
}
function retrieve_latest_wizard_version()
{
$v = false;
$s = trim(remote_file_contents(WIZARD_LATEST_VERSION_URL));
if (preg_match('/^\d+([.]\d+)*$/', $s)) {
$v = $s;
}
return $v;
}
function latest_wizard_version()
{
if (!isset($_SESSION['latest_wizard_version'])) {
$_SESSION['latest_wizard_version'] = retrieve_latest_wizard_version();
}
return $_SESSION['latest_wizard_version'];
}
function update_is_available($lv)
{
if (is_numeric($lv)) {
$lv_parts = explode('.',$lv);
$script_parts = explode('.',script_version());
return ($lv_parts[0] > $script_parts[0] || ($lv_parts[0] == $script_parts[0] && $lv_parts[1] > $script_parts[1]));
} else {
return null;
}
}
function check_for_wizard_update($echo_message = false)
{
$latest_version = latest_wizard_version();
$update_available = update_is_available($latest_version);
if ($update_available) {
if ($echo_message) {
echo '<p class="alert">An updated version of this Wizard script is available <a href="' . LOADER_WIZARD_URL . '">here</a>.</p>';
}
return $latest_version;
} else {
return $update_available;
}
}
function remote_file_contents($url)
{
$remote_file_opening = ini_get('allow_url_fopen');
$contents = false;
if (isset($_SESSION['timing_out']) && $_SESSION['timing_out']) {
return false;
}
@session_write_close();
$timing_out = 0;
if ($remote_file_opening) {
$fh = @fopen($url,'rb');
if ($fh) {
stream_set_blocking($fh,0);
stream_set_timeout($fh,IONCUBE_CONNECT_TIMEOUT);
while (!feof($fh)) {
$result = fread($fh, 8192);
$info = stream_get_meta_data($fh);
$timing_out = $info['timed_out']?1:0;
if ($timing_out) {
break;
}
if ($result !== false) {
$contents .= $result;
} else {
break;
}
}
fclose($fh);
} else {
$timing_out = 1;
}
} elseif (extension_loaded('curl')) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,IONCUBE_CONNECT_TIMEOUT);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
$timing_out = ($info['http_code'] >= 400)?1:0;
curl_close($ch);
if (is_string($output)) {
$contents = $output;
}
} else {
$timing_out = 1;
}
@session_start();
$_SESSION['timing_out'] = $timing_out;
return $contents;
}
function php_version()
{
$v = explode('.',PHP_VERSION);
return array(
'major' => $v[0],
'minor' => $v[1],
'release' => $v[2]);
}
function php_version_maj_min()
{
$vprts = php_version();
return ($vprts['major'] . '.' . $vprts['minor']);
}
function is_supported_php_version()
{
$v = php_version();
return ((($v['major'] == 4) && ($v['minor'] >= 1)) ||
(($v['major'] == 5) && (($v['minor'] >= 1) || ($v['release'] >= 3))) ||
$v['major'] == 7 || ($v['major'] == 8 && $v['minor'] >= 1));
}
function is_php_version_or_greater($major,$minor,$release = 0)
{
$version = php_version();
return ($version['major'] > $major ||
($version['major'] == $major && $version['minor'] > $minor) ||
($version['major'] == $major && $version['minor'] == $minor && $version['release'] >= $release));
}
function ini_file_name()
{
$sysinfo = get_sysinfo();
return (!empty($sysinfo['PHP_INI'])?$sysinfo['PHP_INI_BASENAME']:'php.ini');
}
function get_remote_session_value($session_var,$remote_url,$default_function)
{
if (!isset($_SESSION[$session_var])) {
$serialised_res = remote_file_contents($remote_url);
$unserialised_res = @unserialize($serialised_res);
if (empty($unserialised_res)) {
$unserialised_res = call_user_func($default_function);
} else {
$_SESSION['remote_access_successful'] = 1;
}
if (false === $unserialised_res) {
$unserialised_res = '';
}
$_SESSION[$session_var] = $unserialised_res;
}
return $_SESSION[$session_var];
}
function get_file_contents($file)
{
if (empty($file)) {
return "";
}
if (function_exists('file_get_contents')) {
$strs = @file_get_contents($file);
} else {
$lines = @file($file);
$strs = join(' ',$lines);
}
return $strs;
}
function default_platform_list()
{
$platforms = array();
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC6', 'is_legacy' => 1, 'os_mod' => '_vc6', 'arch'=>'x86', 'dirname'=>'win32', 'us1-dir'=>'windows_vc6/x86' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC6 (Non-TS)', 'is_legacy' => 1, 'os_mod' => '_nonts_vc6', 'arch'=>'x86', 'dirname'=>'win32-nonts', 'us1-dir'=>'windows_vc6/x86-nonts' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC9', 'os_mod' => '_vc9', 'arch'=>'x86', 'dirname'=>'win32_vc9', 'us1-dir'=>'windows_vc9/x86' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC9 (Non-TS)', 'os_mod' => '_nonts_vc9', 'arch'=>'x86', 'dirname'=>'win32-nonts_vc9', 'us1-dir'=>'windows_vc9/x86-nonts' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC11', 'os_mod' => '_vc11', 'arch'=>'x86', 'dirname'=>'win32_vc11', 'us1-dir'=>'windows_vc11/x86' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC11 (Non-TS)', 'os_mod' => '_nonts_vc11', 'arch'=>'x86', 'dirname'=>'win32-nonts_vc11', 'us1-dir'=>'windows_vc11/x86-nonts' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC11', 'os_mod' => '_vc11', 'arch'=>'x86-64', 'dirname'=>'win64_vc11', 'us1-dir'=>'windows_vc11/amd64' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC11 (Non-TS)', 'os_mod' => '_nonts_vc11', 'arch'=>'x86-64', 'dirname'=>'win64-nonts_vc11', 'us1-dir'=>'windows_vc11/amd64-nonts' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC14', 'os_mod' => '_vc14', 'arch'=>'x86', 'dirname'=>'win32_vc14', 'us1-dir'=>'windows_vc14/x86' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC14 (Non-TS)', 'os_mod' => '_nonts_vc14', 'arch'=>'x86', 'dirname'=>'win32-nonts_vc14', 'us1-dir'=>'windows_vc14/x86-nonts' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC14', 'os_mod' => '_vc14', 'arch'=>'x86-64', 'dirname'=>'win64_vc14', 'us1-dir'=>'windows_vc14/amd64' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC14 (Non-TS)', 'os_mod' => '_nonts_vc14', 'arch'=>'x86-64', 'dirname'=>'win64-nonts_vc14', 'us1-dir'=>'windows_vc14/amd64-nonts' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC15', 'os_mod' => '_vc15', 'arch'=>'x86', 'dirname'=>'win32_vc15', 'us1-dir'=>'windows_vc15/x86' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC15 (Non-TS)', 'os_mod' => '_nonts_vc15', 'arch'=>'x86', 'dirname'=>'win32-nonts_vc15', 'us1-dir'=>'windows_vc15/x86-nonts' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC15', 'os_mod' => '_vc15', 'arch'=>'x86-64', 'dirname'=>'win64_vc15', 'us1-dir'=>'windows_vc15/amd64' );
$platforms[] = array('os'=>'win', 'os_human'=>'Windows VC15 (Non-TS)', 'os_mod' => '_nonts_vc15', 'arch'=>'x86-64', 'dirname'=>'win64-nonts_vc15', 'us1-dir'=>'windows_vc15/amd64-nonts' );
$platforms[] = array('os'=>'lin', 'os_human'=>'Linux', 'arch'=>'x86', 'dirname'=>'linux_i686-glibc2.3.4', 'us1-dir'=>'linux/x86');
$platforms[] = array('os'=>'lin', 'os_human'=>'Linux', 'arch'=>'x86-64', 'dirname'=>'linux_x86_64-glibc2.3.4', 'us1-dir'=>'linux/x86_64');
$platforms[] = array('os'=>'lin','os_human'=>'Linux', 'arch'=>'ppc', 'dirname'=>'linux_ppc-glibc2.3.4','us1-dir'=>'linux/ppc');
$platforms[] = array('os'=>'lin','os_human'=>'Linux', 'arch'=>'ppc64', 'dirname'=>'linux_ppc64-glibc2.5','us1-dir'=>'linux/ppc64');
$platforms[] = array('os'=>'dra', 'os_human'=>'DragonFly', 'arch'=>'x86', 'dirname'=>'dragonfly_i386-1.7', 'us1-dir'=>'Dragonfly/x86');
$platforms[] = array('os'=>'fre', 'os_human'=>'FreeBSD 4', 'os_mod'=>'_4', 'arch'=>'x86', 'dirname'=>'freebsd_i386-4.8', 'us1-dir'=>'FreeBSD/v4');
$platforms[] = array('os'=>'fre', 'os_human'=>'FreeBSD 6', 'os_mod'=>'_6', 'arch'=>'x86', 'dirname'=>'freebsd_i386-6.2', 'us1-dir'=>'FreeBSD/v6/x86');
$platforms[] = array('os'=>'fre', 'os_human'=>'FreeBSD 6', 'os_mod'=>'_6', 'arch'=>'x86-64', 'dirname'=>'freebsd_amd64-6.2', 'us1-dir'=>'FreeBSD/v6/AMD64');
$platforms[] = array('os'=>'fre', 'os_human'=>'FreeBSD 7', 'os_mod'=>'_7', 'arch'=>'x86', 'dirname'=>'freebsd_i386-7.3', 'us1-dir'=>'FreeBSD/v7/x86');
$platforms[] = array('os'=>'fre', 'os_human'=>'FreeBSD 7', 'os_mod'=>'_7', 'arch'=>'x86-64', 'dirname'=>'freebsd_amd64-7.3', 'us1-dir'=>'FreeBSD/v7/AMD64');
$platforms[] = array('os'=>'fre', 'os_human'=>'FreeBSD 8', 'os_mod'=>'_8', 'arch'=>'x86', 'dirname'=>'freebsd_i386-8.0', 'us1-dir'=>'FreeBSD/v8/x86');
$platforms[] = array('os'=>'fre', 'os_human'=>'FreeBSD 8', 'os_mod'=>'_8', 'arch'=>'x86-64', 'dirname'=>'freebsd_amd64-8.0', 'us1-dir'=>'FreeBSD/v8/AMD64');
$platforms[] = array('os'=>'bsd', 'os_human'=>'BSDi', 'is_legacy' => 1, 'arch'=>'x86', 'dirname'=>'bsdi_i386-4.3.1');
$platforms[] = array('os'=>'net', 'os_human'=>'NetBSD', 'arch'=>'x86', 'dirname'=>'netbsd_i386-2.1','us1-dir'=>'NetBSD/x86');
$platforms[] = array('os'=>'net', 'os_human'=>'NetBSD', 'arch'=>'x86-64', 'dirname'=>'netbsd_amd64-2.0','us1-dir'=>'NetBSD/x86_64');
$platforms[] = array('os'=>'ope', 'os_human'=>'OpenBSD 4.2', 'os_mod'=>'_4.2', 'arch'=>'x86', 'dirname'=>'openbsd_i386-4.2', 'us1-dir'=>'OpenBSD/x86');
$platforms[] = array('os'=>'ope', 'os_human'=>'OpenBSD 4.5', 'os_mod'=>'_4.5', 'arch'=>'x86', 'dirname'=>'openbsd_i386-4.5', 'us1-dir'=>'OpenBSD/x86');
$platforms[] = array('os'=>'ope', 'os_human'=>'OpenBSD 4.6', 'os_mod'=>'_4.6', 'arch'=>'x86', 'dirname'=>'openbsd_i386-4.6', 'us1-dir'=>'OpenBSD/x86');
$platforms[] = array('os'=>'ope', 'os_human'=>'OpenBSD 4.7', 'os_mod'=>'_4.7', 'arch'=>'x86-64', 'dirname'=>'openbsd_amd64-4.7', 'us1-dir' => 'OpenBSD/x86_64');
$platforms[] = array('os'=>'dar', 'os_human'=>'OS X', 'is_legacy' => 1, 'arch'=>'ppc', 'dirname'=>'osx_powerpc-8.5','us1-dir'=>'OSX/ppc');
$platforms[] = array('os'=>'dar', 'os_human'=>'OS X', 'arch'=>'x86', 'dirname'=>'osx_i386-8.11','us1-dir'=>'OSX/x86');
$platforms[] = array('os'=>'dar', 'os_human'=>'OS X', 'arch'=>'x86-64', 'dirname'=>'osx_x86-64-10.2','us1-dir'=>'OSX/x86_64');
$platforms[] = array('os'=>'sun', 'os_human'=>'Solaris', 'is_legacy' => 1, 'arch'=>'sparc', 'dirname'=>'solaris_sparc-5.9', 'us1-dir'=>'Solaris/sparc');
$platforms[] = array('os'=>'sun', 'os_human'=>'Solaris', 'arch'=>'x86', 'dirname'=>'solaris_i386-5.10','us1-dir'=>'Solaris/x86');
return $platforms;
}
function get_loader_platforms()
{
return get_remote_session_value('loader_platform_info',LOADER_PLATFORM_URL,'default_platform_list');
}
function get_platforminfo()
{
static $platforminfo;
if (empty($platforminfo)) {
$platforminfo = get_loader_platforms();
}
return $platforminfo;
}
function default_php_versions()
{
return array();
}
function get_php_versions()
{
return get_remote_session_value('php_version_info',LOADER_PHP_VERSION_URL,'default_php_versions');
}
function get_max_php_version_supported()
{
static $max_php_version;
if (empty($max_php_version)) {
$php_versions = get_php_versions();
$dirname = calc_dirname();
if (array_key_exists($dirname,$php_versions)) {
$max_php_version = $php_versions[$dirname];
} else {
$max_php_version = NULL;
}
}
return $max_php_version;
}
function is_after_max_php_version_supported()
{
$is_too_recent_php = false;
$supported_php_version = get_max_php_version_supported();
if (!is_null($supported_php_version)) {
$pversion = php_version();
$supported_parts = explode('.',$supported_php_version);
$is_too_recent_php = ($supported_parts[0] < $pversion['major'] || ($supported_parts[0] == $pversion['major'] && $supported_parts[1] < $pversion['minor']));
}
if ($is_too_recent_php) {
return $supported_php_version;
} else {
return false;
}
}
function supported_os_variants($os_code,$arch_code)
{
if (empty($os_code)) {
return ERROR_UNKNOWN_OS;
}
if (empty($arch_code)) {
return ERROR_UNKNOWN_ARCH;
}
$os_found = false;
$arch_found = false;
$os_arch_matches = array();
$pinfo = get_platforminfo();
foreach ($pinfo as $p) {
if ($p['os'] == $os_code && $p['arch'] == $arch_code) {
$os_arch_matches[$p['os_human']] = (isset($p['os_mod']))?(0 + (int) str_replace('_','',$p['os_mod'])):'';
}
if ($p['os'] == $os_code) {
$os_found = true;
} elseif ($p['arch'] == $arch_code) {
$arch_found = true;
}
}
if (!empty($os_arch_matches)) {
asort($os_arch_matches);
return $os_arch_matches;
} elseif (!$os_found) {
return ERROR_UNSUPPORTED_OS;
} elseif (!$arch_found) {
return ERROR_UNSUPPORTED_ARCH;
} else {
return ERROR_UNSUPPORTED_ARCH_OS;
}
}
function default_win_compilers()
{
return array('VC6','VC9','VC11','VC14','VC15', 'VC16');
}
function supported_win_compilers()
{
static $win_compilers;
if (empty($win_compilers)) {
$win_compilers = find_win_compilers();
}
return $win_compilers;
}
function find_win_compilers()
{
return get_remote_session_value('php_compilers_info',PHP_COMPILERS_URL,'default_win_compilers');
}
function server_software_info()
{
$ss = array('full' => '','short' => '');
$ss['full'] = $_SERVER['SERVER_SOFTWARE'];
if (preg_match('/apache/i', $ss['full'])) {
$ss['short'] = 'Apache';
} else if (preg_match('/IIS/',$ss['full'])) {
$ss['short'] = 'IIS';
} else {
$ss['short'] = '';
}
return $ss;
}
function match_arch_pattern($str)
{
$arch = null;
$arch_patterns = array(
'i.?86' => 'x86',
'x86[-_]64' => 'x86',
'x86' => 'x86',
'amd64' => 'x86',
'SMP Tue Jan 01 00:00:00 CEST 2000 all GNU\/Linux' => 'x86',
'ppc64' => 'ppc',
'ppc' => 'ppc',
'powerpc' => 'ppc',
'sparc' => 'sparc',
'sun' => 'sparc',
'armv7l' => 'armv7l',
'aarch64' => 'aarch64'
);
foreach ($arch_patterns as $token => $a) {
if (preg_match("/$token/i", $str)) {
$arch = $a;
break;
}
}
return $arch;
}
function required_loader_arch($mach_info,$os_code,$wordsize)
{
if ($os_code == 'win') {
$arch = ($wordsize == 32)?'x86':'x86-64';
} elseif (!empty($os_code)) {
$arch = match_arch_pattern($mach_info);
if ($wordsize == 64) {
if ($arch == 'x86') {
$arch = 'x86-64';
} elseif ($arch == 'ppc') {
$arch = 'ppc64';
}
}
} else {
$arch = ERROR_UNKNOWN_ARCH;
}
return $arch;
}
function uname($part = 'a')
{
$result = '';
if (!function_is_disabled('php_uname')) {
$result = @php_uname($part);
} elseif (function_exists('posix_uname') && !function_is_disabled('posix_uname')) {
$posix_equivs = array(
'm' => 'machine',
'n' => 'nodename',
'r' => 'release',
's' => 'sysname'
);
$puname = @posix_uname();
if ($part == 'a' || !array_key_exists($part,$posix_equivs)) {
$result = join(' ',$puname);
} else {
$result = $puname[$posix_equivs[$part]];
}
} else {
if (!function_is_disabled('phpinfo')) {
ob_start();
phpinfo(INFO_GENERAL);
$pinfo = ob_get_contents();
ob_end_clean();
if (preg_match('~System.*?(</B></td><TD ALIGN="left">| => |v">)([^<]*)~i',$pinfo,$match)) {
$uname = $match[2];
if ($part == 'r') {
if (!empty($uname) && preg_match('/\S+\s+\S+\s+([0-9.]+)/',$uname,$matchver)) {
$result = $matchver[1];
} else {
$result = '';
}
} else {
$result = $uname;
}
}
} else {
$result = '';
}
}
return $result;
}
function calc_word_size($os_code)
{
$wordsize = null;
if ('win' === $os_code) {
ob_start();
phpinfo(INFO_GENERAL);
$pinfo = ob_get_contents();
ob_end_clean();
if (preg_match('~Compiler.*?(</B></td><TD ALIGN="left">| => |v">)([^<]*)~i',$pinfo,$compmatch)) {
if (preg_match("/(VC[0-9]+)/i",$compmatch[2],$vcmatch)) {
$compiler = strtoupper($vcmatch[1]);
} elseif (stripos(trim($compmatch[2]),"Visual C++ 2019") === 0) {
$compiler = 'VC16';
} else {
$compiler = 'VC6';
}
} else {
$compiler = 'VC6';
}
if ($compiler === 'VC9' || $compiler === 'VC11' || $compiler === 'VC14'
|| $compiler === 'VC15' || $compiler === 'VC16') {
if (preg_match('~Architecture.*?(</B></td><TD ALIGN="left">| => |v">)([^<]*)~i',$pinfo,$archmatch)) {
if (preg_match("/x64/i",$archmatch[2])) {
$wordsize = 64;
} else {
$wordsize = 32;
}
} elseif (isset($_ENV['PROCESSOR_ARCHITECTURE']) && preg_match('~(amd64|x86-64|x86_64)~i',$_ENV['PROCESSOR_ARCHITECTURE'])) {
if (preg_match('~Configure Command.*?(</B></td><TD ALIGN="left">| => |v">)([^<]*)~i',$pinfo,$confmatch)) {
if (preg_match('~(x64|lib64|system64)~i',$confmatch[2])) {
$wordsize = 64;
}
}
} else {
$wordsize = 32;
}
}
}
if (empty($wordsize)) {
$wordsize = ((-1^0xffffffff)?64:32);
}
return $wordsize;
}
function required_loader($unamestr = '')
{
$un = empty($unamestr)?uname():$unamestr;
$php_major_version = substr(PHP_VERSION,0,3);
$os_name = substr($un,0,strpos($un,' '));
$os_code = empty($os_name)?'':strtolower(substr($os_name,0,3));
$wordsize = calc_word_size($os_code);
if ($os_code == 'win' && $wordsize == 64 && $php_major_version < '5.5') {
$arch = ERROR_WINDOWS_64_BIT;
} else {
$arch = required_loader_arch($un,$os_code,$wordsize);
}
if (!is_string($arch)) {
return $arch;
}
$os_variants = supported_os_variants($os_code,$arch);
if (!is_array($os_variants)) {
return $os_variants;
}
$os_ver = '';
if (preg_match('/([0-9.]+)/',uname('r'),$match)) {
$os_ver = $match[1];
}
$os_ver_parts = preg_split('@\.@',$os_ver);
$os_code_h = ($os_code == 'dar' ? 'mac' : $os_code);
$loader_sfix = (($os_code == 'win') ? 'dll' : 'so');
$file = "ioncube_loader_{$os_code_h}_{$php_major_version}.{$loader_sfix}";
if ($os_code == 'win') {
$os_name = 'Windows';
$file_ts = $file;
$os_name_qual = 'Windows';
} else {
$os_names = array_keys($os_variants);
if (count($os_variants) > 1) {
$parts = explode(" ",$os_names[0]);
$os_name = $parts[0];
$os_name_qual = $os_name . ' ' . $os_ver_parts[0] . '.' . $os_ver_parts[1];
} else {
$os_name = $os_names[0];
$os_name_qual = $os_name;
}
$file_ts = "ioncube_loader_{$os_code_h}_{$php_major_version}_ts.{$loader_sfix}";
}
return array(
'uname' => $un,
'arch' => $arch,
'oscode' => $os_code,
'oscode_h' => $os_code_h,
'osname' => $os_name,
'osnamequal' => $os_name_qual,
'osvariants' => $os_variants,
'osver' => $os_ver,
'osver2' => $os_ver_parts,
'file' => $file,
'file_ts' => $file_ts,
'wordsize' => $wordsize
);
}
function ic_system_info()
{
$thread_safe = null;
$debug_build = null;
$cgi_cli = false;
$is_fpm = false;
$is_cgi = false;
$is_cli = false;
$php_ini_path = '';
$php_ini_dir = '';
$php_ini_add = '';
$is_supported_compiler = true;
$php_compiler = is_ms_windows()?'VC6':'';
ob_start();
phpinfo(INFO_GENERAL);
$php_info = ob_get_contents();
ob_end_clean();
$breaker = (php_sapi_name() == 'cli')?"\n":'</tr>';
$lines = explode($breaker,$php_info);
foreach ($lines as $line) {
if (preg_match('/command/i',$line)) {
continue;
}
if (preg_match('/thread safety/i', $line)) {
$thread_safe = (preg_match('/(enabled|yes)/i', $line) != 0);
}
if (preg_match('/debug build/i', $line)) {
$debug_build = (preg_match('/(enabled|yes)/i', $line) != 0);
}
if (preg_match('~configuration file.*(</B></td><TD ALIGN="left">| => |v">)([^ <]*)~i',$line,$match)) {
$php_ini_path = $match[2];
if (!@file_exists($php_ini_path)) {
$php_ini_path = '';
}
}
if (preg_match('~dir for additional \.ini files.*(</B></td><TD ALIGN="left">| => |v">)([^ <]*)~i',$line,$match)) {
$php_ini_dir = $match[2];
if (!@file_exists($php_ini_dir)) {
$php_ini_dir = '';
}
}
if (preg_match('~additional \.ini files parsed.*(</B></td><TD ALIGN="left">| => |v">)([^ <]*)~i',$line,$match)) {
$php_ini_add = $match[2];
}
if (preg_match('/compiler/i',$line)) {
$supported_match = join('|',supported_win_compilers());
$is_supported_compiler = preg_match("/($supported_match)/i",$line);
if (preg_match("/(VC[0-9]+)/i",$line,$match)) {
$php_compiler = strtoupper($match[1]);
} elseif (preg_match("/Visual C\+\+ 2017/i",$line)) {
$php_compiler = "VC15";
$is_supported_compiler = true;
} elseif (preg_match("/Visual C\+\+ 2019/i",$line)) {
$php_compiler = "VC16";
$is_supported_compiler = true;
} else {
$php_compiler = '';
}
}
}
$is_cgi = strpos(php_sapi_name(),'cgi') !== false;
$is_cli = strpos(php_sapi_name(),'cli') !== false;
$is_fpm = strpos(php_sapi_name(),'fpm-fcgi') !== false;
$cgi_cli = $is_cgi || $is_cli;
$ss = server_software_info();
if ($is_fpm) {
$ss['short'] = 'PHP-FPM';
$ss['full'] = 'PHP-FPM ' . $ss['full'];
}
if (!$php_ini_path && function_exists('php_ini_loaded_file')) {
$php_ini_path = php_ini_loaded_file();
if ($php_ini_path === false) {
$php_ini_path = '';
}
}
if (!empty($php_ini_path)) {
$real_path = @realpath($php_ini_path);
if (false !== $real_path) {
$php_ini_path = $real_path;
}
}
$php_ini_basename = basename($php_ini_path);
return array(
'THREAD_SAFE' => $thread_safe,
'DEBUG_BUILD' => $debug_build,
'PHP_INI' => $php_ini_path,
'PHP_INI_BASENAME' => $php_ini_basename,
'PHP_INI_DIR' => $php_ini_dir,
'PHP_INI_ADDITIONAL' => $php_ini_add,
'PHPRC' => getenv('PHPRC'),
'CGI_CLI' => $cgi_cli,
'IS_CGI' => $is_cgi,
'IS_CLI' => $is_cli,
'IS_FPM' => $is_fpm,
'PHP_COMPILER' => $php_compiler,
'SUPPORTED_COMPILER' => $is_supported_compiler,
'FULL_SS' => $ss['full'],
'SS' => $ss['short']);
}
function is_possibly_dedicated_or_local()
{
$sys = get_sysinfo();
return (empty($sys['PHP_INI']) || !@file_exists($sys['PHP_INI']) || (is_readable($sys['PHP_INI']) && (0 !== strpos($sys['PHP_INI'],$_SERVER['DOCUMENT_ROOT']))));
}
function is_local()
{
$ret = false;
if ($_SERVER["SERVER_NAME"] == 'localhost') {
$ret = true;
} else {
$ip_address = strtolower($_SERVER["REMOTE_ADDR"]);
if (strpos(':',$ip_address) === false) {
$ip_parts = explode('.',$ip_address);
$ret = (($ip_parts[0] == 10) ||
($ip_parts[0] == 172 && $ip_parts[1] >= 16 && $ip_parts[1] <= 31) ||
($ip_parts[0] == 192 && $ip_parts[1] == 168));
} else {
$ret = ($ip_address == '::1') || (($ip_address[0] == 'f') && ($ip_address[1] >= 'c' && $ip_address[1] <= 'f'));
}
}
return $ret;
}
function is_shared()
{
return !is_local() && !is_possibly_dedicated_or_local();
}
function find_server_type($chosen_type = '',$type_must_be_chosen = false,$set_session = false)
{
$server_type = SERVER_UNKNOWN;
if (empty($chosen_type)) {
if ($type_must_be_chosen) {
$server_type = SERVER_UNKNOWN;
} else {
if (isset($_SESSION['server_type']) && $_SESSION['server_type'] != SERVER_UNKNOWN) {
$server_type = $_SESSION['server_type'];
} elseif (is_local()) {
$server_type = SERVER_LOCAL;
} elseif (!is_possibly_dedicated_or_local()) {
$server_type = SERVER_SHARED;
} else {
$server_type = SERVER_UNKNOWN;
}
}
} else {
switch ($chosen_type) {
case 's':
$server_type = SERVER_SHARED;
break;
case 'd':
$server_type = SERVER_DEDICATED;
break;
case 'l':
$server_type = SERVER_LOCAL;
break;
default:
$server_type = SERVER_UNKNOWN;
break;
}
}
if ($set_session) {
$_SESSION['server_type'] = $server_type;
}
return $server_type;
}
function server_type_string()
{
$server_code = find_server_type();
switch ($server_code) {
case SERVER_SHARED:
$server_string = 'SHARED';
break;
case SERVER_LOCAL:
$server_string = 'LOCAL';
break;
case SERVER_DEDICATED:
$server_string = 'DEDICATED';
break;
default:
$server_string = 'UNKNOWN';
break;
}
return $server_string;
}
function server_type_code()
{
$server_code = find_server_type();
switch ($server_code) {
case SERVER_SHARED:
$server_char = 's';
break;
case SERVER_LOCAL:
$server_char = 'l';
break;
case SERVER_DEDICATED:
$server_char = 'd';
break;
default:
$server_char = '';
break;
}
return $server_char;
}
function get_sysinfo()
{
static $sysinfo;
if (empty($sysinfo)) {
$sysinfo = ic_system_info();
}
return $sysinfo;
}
function get_loaderinfo()
{
static $loader;
if (empty($loader)) {
$loader = required_loader();
}
return $loader;
}
function is_ms_windows()
{
$loader_info = get_loaderinfo();
return ($loader_info['oscode'] == 'win');
}
function function_is_disabled($fn_name)
{
$disabled_functions=explode(',',ini_get('disable_functions'));
return in_array($fn_name, $disabled_functions);
}
function selinux_is_enabled()
{
$se_enabled = false;
if (!is_ms_windows()) {
$cmd = (string) @shell_exec('sestatus');
$se_enabled = preg_match('/enabled/i',$cmd);
}
return $se_enabled;
}
function grsecurity_is_enabled()
{
$gr_enabled = false;
if (!is_ms_windows()) {
$cmd = (string) @shell_exec('gradm -S');
$gr_enabled = preg_match('/enabled/i',$cmd);
}
return $gr_enabled;
}
function threaded_and_not_cgi()
{
$sys = get_sysinfo();
return($sys['THREAD_SAFE'] && !$sys['IS_CGI']);
}
function is_restricted_server($only_safe_mode = false)
{
$disable_functions = ini_get('disable_functions');
$open_basedir = ini_get('open_basedir');
$php_restrictions = !empty($disable_functions) || !empty($open_basedir);
$system_restrictions = selinux_is_enabled() || grsecurity_is_enabled();
$non_safe_mode_restrictions = $php_restrictions || $system_restrictions;
return (ini_get('safe_mode') || (!$only_safe_mode && $non_safe_mode_restrictions));
}
function server_restriction_warnings()
{
$warnings = array();
if (find_server_type() == SERVER_SHARED) {
if (is_restricted_server()) {
$warnings[] = "Server restrictions are in place which might affect the operation of this Loader Wizard or prevent the installation of the Loader.";
}
} else {
$warning_suffix = "This may affect the operation of this Loader Wizard.";
if (ini_get('safe_mode')) {
$warnings[] = "Safe mode is in effect on the server. " . $warning_suffix;
}
$disabled_functions = ini_get('disable_functions');
if (!empty($disabled_functions)) {
$warnings[] = "Some functions are disabled through disable_functions. " . $warning_suffix;
}
$open_basedir = ini_get('open_basedir');
if (!empty($open_basedir)) {
$warnings[] = "Open basedir restrictions are in effect. " . $warning_suffix;
}
}
return $warnings;
}
function own_php_ini_possible($only_safe_mode = false)
{
$sysinfo = get_sysinfo();
return ($sysinfo['CGI_CLI'] && !is_ms_windows() && !is_restricted_server($only_safe_mode));
}
function extension_dir()
{
$extdir = ini_get('extension_dir');
if ($extdir == './' || ($extdir == '.\\' && is_ms_windows())) {
$extdir = '.';
}
return $extdir;
}
function possibly_selinux()
{
$loaderinfo = get_loaderinfo();
$se_env = (getenv("SELINUX_INIT"));
return (strtolower($loaderinfo['osname']) == 'linux' && $se_env && ($se_env == 'Yes' || $se_env == '1'));
}
function ini_same_dir_as_wizard()
{
$sys = get_sysinfo();
return dirname($sys['PHP_INI']) == dirname(__FILE__);
}
function extension_dir_path()
{
$ext_dir = extension_dir();
if ($ext_dir == '.' || (dirname($ext_dir) == '.')) {
$ext_dir_path = @realpath($ext_dir);
} else {
$ext_dir_path = $ext_dir;
}
return $ext_dir_path;
}
function get_loader_name()
{
$u = uname();
$sys = get_sysinfo();
$os = substr($u,0,strpos($u,' '));
$os_code = strtolower(substr($u,0,3));
$os_code_h = ($os_code == 'dar' ? 'mac' : $os_code);
$php_version = phpversion();
$php_family = substr($php_version,0,3);
$loader_sfix = (($os_code == 'win') ? '.dll' : (($sys['THREAD_SAFE'])?'_ts.so':'.so'));
$loader_name="ioncube_loader_{$os_code_h}_{$php_family}{$loader_sfix}";
return $loader_name;
}
function get_reqd_version($variants)
{
$exact_match = false;
$nearest_version = 0;
$loader_info = get_loaderinfo();
$os_version = $loader_info['osver2'][0] . '.' . $loader_info['osver2'][1];
$os_version_major = $loader_info['osver2'][0];
foreach ($variants as $v) {
if ($v == $os_version || (is_int($v) && $v == $os_version_major)) {
$exact_match = true;
$nearest_version = $v;
break;
} elseif ($v > $os_version) {
break;
} else {
$nearest_version = $v;
}
}
return (array($nearest_version,$exact_match));
}
function get_default_loader_dir_webspace()
{
return ($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . LOADER_SUBDIR);
}
function get_loader_location($loader_dir = '')
{
if (empty($loader_dir)) {
$loader_dir = get_default_loader_dir_webspace();
}
$loader_name = get_loader_name();
return ($loader_dir . DIRECTORY_SEPARATOR . $loader_name);
}
function get_loader_location_from_ini($php_ini = '')
{
$errors = array();
if (empty($php_ini)) {
$sysinfo = get_sysinfo();
$php_ini = $sysinfo['PHP_INI'];
}
if (!@file_exists($php_ini)) {
if (empty($php_ini)) {
$errors[ERROR_INI_NOT_FOUND] = "The configuration file could not be found.";
} else {
$errors[ERROR_INI_NOT_FOUND] = "The $php_ini file could not be found.";
}
} elseif (!is_readable($php_ini)) {
$errors[ERROR_INI_NOT_READABLE] = "The $php_ini file could not be read.";
}
if (!empty($errors)) {
return array('location' => '', 'errors' => $errors);
}
$lines = file($php_ini);
$ext_start = zend_extension_line_start();
$wrong_ext_start = ($ext_start == 'zend_extension')?'zend_extension_ts':'zend_extension';
$loader_path = '';
$loader_name_match = "ioncube_loader";
foreach ($lines as $l) {
if (preg_match("/^\s*$ext_start\s*=\s*\"?([^\"]+)\"?/i",$l,$corr_matches)) {
if (preg_match("/$loader_name_match/i",$corr_matches[1])) {
if (!empty($loader_path)) {
$errors[ERROR_INI_MULTIPLE_IC_LOADER_LINES] = "It appears that multiple $ext_start lines for the ionCube Loader have been included in the configuration file, $php_ini.";
}
$loader_path = $corr_matches[1];
} else {
if (empty($loader_path)) {
$errors[ERROR_INI_NOT_FIRST_ZE] = "The ionCube Loader must be the first Zend extension listed in the configuration file, $php_ini.";
}
}
}
if (empty($loader_path)) {
if (preg_match("/^\s*$wrong_ext_start\s*=\s*\"?([^\"]+)\"?/i",$l,$bad_start_matches)) {
if (preg_match("/$loader_name_match/i",$bad_start_matches[1])) {
$bad_zend_ext_msg = "The line for the ionCube Loader in the configuration file, $php_ini, should start with $ext_start and <b>not</b> $wrong_ext_start.";
$errors[ERROR_INI_WRONG_ZE_START] = $bad_zend_ext_msg;
$loader_path = $bad_start_matches[1];
}
}
}
}
$loader_path = trim($loader_path);
if ($loader_path === '') {
$errors[ERROR_INI_ZE_LINE_NOT_FOUND] = "The necessary zend_extension line could not be found in the configuration file, $php_ini.";
} elseif (!@file_exists($loader_path)) {
$errors[ERROR_INI_LOADER_FILE_NOT_FOUND] = "The loader file $loader_path, listed in the configuration file, $php_ini, does not exist or is not accessible.";
} elseif (basename($loader_path) == $loader_path) {
$errors[ERROR_INI_NOT_FULL_PATH] = "A full path must be specified for the loader file in the configuration file, $php_ini.";
}
return array('location' => $loader_path, 'errors' => $errors);
}
function zend_extension_line_missing($ini_path)
{
$loader_loc = get_loader_location_from_ini($ini_path);
return (!empty($loader_loc['errors']) && array_key_exists(ERROR_INI_ZE_LINE_NOT_FOUND,$loader_loc['errors']));
}
function find_additional_ioncube_ini()
{
$sys = get_sysinfo();
$ioncube_ini = '';
if (!empty($sys['PHP_INI_ADDITIONAL']) && !preg_match('/(none)/i',$sys['PHP_INI_ADDITIONAL'])) {
$ini_files = explode(',',$sys['PHP_INI_ADDITIONAL']);
foreach ($ini_files as $f) {
$fn = trim($f);
$bfn = basename($fn);
if (preg_match('/ioncube/i',$bfn)) {
$ioncube_ini = $fn;
break;
}
}
}
return $ioncube_ini;
}
function get_additional_ini_files()
{
$sys = get_sysinfo();
$ini_files = array();
if (!empty($sys['PHP_INI_ADDITIONAL']) && !preg_match('/(none)/i',$sys['PHP_INI_ADDITIONAL'])) {
$ini_files = explode(',',$sys['PHP_INI_ADDITIONAL']);
}
return (array_map('trim',$ini_files));
}
function all_ini_contents()
{
$sys = get_sysinfo();
$output = '';
$output .= ";;; *MAIN INI FILE AT {$sys['PHP_INI']}* ;;;" . PHP_EOL;
$output .= get_file_contents($sys['PHP_INI']);
$other_inis = get_additional_ini_files();
foreach ($other_inis as $inif) {
$output .= ";;; *Additional ini file at $inif* ;;;" . PHP_EOL;
$output .= get_file_contents($inif);
}
$here = unix_path_dir();
$unrec_ini_files = unrecognised_inis_webspace($here);
foreach ($unrec_ini_files as $urinif) {
$output .= ";;; *UNRECOGNISED INI FILE at $urinif* ;;;" . PHP_EOL;
$output .= get_file_contents($urinif);
}
return $output;
}
function scan_inis_for_loader()
{
$ldloc = array('location' => '', 'errors' => array());
$sysinfo = get_sysinfo();
if (empty($sysinfo['PHP_INI'])) {
$ini_files_not_found = array("Main ini file");
$ini_file_list = get_additional_ini_files();
} else {
$ini_files_not_found = array();
$ini_file_list = array_merge(array($sysinfo['PHP_INI']),get_additional_ini_files());
}
$server_type = find_server_type();
$shared_server = SERVER_SHARED == $server_type;
foreach ($ini_file_list as $f) {
$ldloc = get_loader_location_from_ini($f);
if (array_key_exists(ERROR_INI_ZE_LINE_NOT_FOUND,$ldloc['errors'])) {
unset($ldloc['errors'][ERROR_INI_ZE_LINE_NOT_FOUND]);
}
if ($shared_server && array_key_exists(ERROR_INI_NOT_FOUND,$ldloc['errors'])) {
if (false == user_ini_space_path($f)) {
$ldloc['errors'][ERROR_INI_NOT_FOUND] = "A system ini file cannot be found or read by the Wizard - you cannot do anything about this on your shared server.";
} else {
$ldloc['errors'][ERROR_INI_USER_INI_NOT_FOUND] = $ldloc['errors'][ERROR_INI_NOT_FOUND];
}
} elseif (array_key_exists(ERROR_INI_NOT_FOUND,$ldloc['errors'])) {
$ini_files_not_found[] = $f;
}
if (!empty($ldloc['location'])) {
break;
}
}
if (!empty($ini_files_not_found)) {
$plural = (count($ini_files_not_found) > 1)?"s":"";
$ldloc['errors'][ERROR_INI_NOT_FOUND] = "The following ini file$plural could not be found by the Wizard: " . join(',',$ini_files_not_found);
if (is_restricted_server()) {
$ldloc['errors'][ERROR_INI_NOT_FOUND] .= "<br> This may be due to server restrictions in place.";
}
}
if (empty($ldloc['location'])) {
$ldloc['errors'][ERROR_INI_ZE_LINE_NOT_FOUND] = "The necessary zend_extension line could not be found in the configuration.";
}
return $ldloc;
}
function find_loader_filesystem()
{
$ld_inst_dir = loader_install_dir(find_server_type());
$loader_name = get_loader_name();
$suggested_loader_path = $ld_inst_dir . DIRECTORY_SEPARATOR . $loader_name;
if (@file_exists($suggested_loader_path)) {
$location = $suggested_loader_path;
} elseif (@file_exists($loader_name)) {
$location = @realpath($loader_name);
} else {
$ld_loc = get_loader_location();
if (@file_exists($ld_loc)) {
$location = $ld_loc;
} else {
$location = '';
}
}
return $location;
}
function find_loader($search_directories_if_not_ini = false)
{
$sysinfo = get_sysinfo();
$php_ini = $sysinfo['PHP_INI'];
$rtl_path = get_runtime_loading_path_if_applicable();
$location = '';
$errors = array();
if (!empty($rtl_path)) {
$location = $rtl_path;
} else {
$loader_ini = scan_inis_for_loader();
$location = $loader_ini['location'];
$errors = $loader_ini['errors'];
}
if (empty($location) && (empty($errors) || $search_directories_if_not_ini)) {
$errors = array();
$location = find_loader_filesystem();
if (empty($location)) {
$errors[ERROR_LOADER_NOT_FOUND] = 'The loader file could not be found in standard locations.';
}
}
if (!empty($errors)) {
return $errors;
} else {
return $location;
}
}
function zend_extension_line_start()
{
$sysinfo = get_sysinfo();
$is_53_or_later = is_php_version_or_greater(5,3);
return (is_bool($sysinfo['THREAD_SAFE']) && $sysinfo['THREAD_SAFE'] && !$is_53_or_later ? 'zend_extension_ts' : 'zend_extension');
}
function ioncube_loader_version_information()
{
$old_version = true;
$liv = "";
$lv = "";
$mv = 0;
if (function_exists('ioncube_loader_iversion')) {
$liv = ioncube_loader_iversion();
$lv = sprintf("%d.%d.%d", $liv / 10000, ($liv / 100) % 100, $liv % 100);
$latest_version = get_latestversion();
$lat_parts = explode('.',$latest_version);
$cur_parts = explode('.',$lv);
if (($cur_parts[0] > $lat_parts[0]) ||
($cur_parts[0] == $lat_parts[0] && $cur_parts[1] > $lat_parts[1]) ||
($cur_parts[0] == $lat_parts[0] && $cur_parts[1] == $lat_parts[1] && $cur_parts[2] >= $lat_parts[2])) {
$old_version = false;
} else {
$old_version = $latest_version;
}
$mv = $cur_parts[0];
}
return array($lv,$mv,$old_version);
}
function default_loader_version_info()
{
return array();
}
function get_loader_version_info()
{
return get_remote_session_value('loader_version_info',LOADER_LATEST_VERSIONS_URL,'default_loader_version_info');
}
function calc_platform()
{
$platform = array();
$platform_info = get_platforminfo();
$loader = get_loaderinfo();
$multiple_os_versions = false;
if (is_array($loader) && array_key_exists('osvariants',$loader) && is_array($loader['osvariants'])) {
$versions = array_values($loader['osvariants']);
$multiple_os_versions = !empty($versions[0]);
}
if ($multiple_os_versions) {
list($osvar,$exact_match) = get_reqd_version($loader['osvariants']);
} else {
$osvar = null;
if (is_ms_windows()) {
$sys = get_sysinfo();
$phpc = (empty($sys['PHP_COMPILER']))?'vc6':strtolower($sys['PHP_COMPILER']);
$osvar = ($sys['THREAD_SAFE']?'':'nonts_') . $phpc;
}
}
foreach ($platform_info as $p) {
if ($p['os'] == $loader['oscode'] && $p['arch'] == $loader['arch'] && (empty($osvar) || $p['os_mod'] == "_" . $osvar)) {
$platform = $p;
break;
}
}
return $platform;
}
function get_platform()
{
static $this_platform;
if (!isset($this_platform)) {
$this_platform = calc_platform();
}
return $this_platform;
}
function is_legacy_platform()
{
$platform = get_platform();
return array_key_exists('is_legacy',$platform);
}
function calc_dirname()
{
$dirname = '';
$platform = get_platform();
if (!empty($platform)) {
$dirname = $platform['dirname'];
}
return $dirname;
}
function calc_loader_latest_version()
{
$lv_info = get_loader_version_info();
$latest_version = RECENT_LOADER_VERSION;
if (!empty($lv_info)) {
$dirname = calc_dirname();
if (!empty($dirname)) {
$compiler_specific_version = false;
if (is_ms_windows()) {
$sys = get_sysinfo();
$phpc = strtolower($sys['PHP_COMPILER']);
if (!empty($phpc)) {
$dirname_comp = $dirname . "_" . $phpc;
if (array_key_exists($dirname_comp,$lv_info)) {
$latest_version = $lv_info[$dirname_comp];
$compiler_specific_version = true;
}
}
}
if (!$compiler_specific_version && array_key_exists($dirname,$lv_info)) {
$latest_version = $lv_info[$dirname];
}
}
}
return $latest_version;
}
function get_latestversion()
{
static $latest_version;
if (empty($latest_version)) {
$latest_version = calc_loader_latest_version();
}
return $latest_version;
}
function runtime_loader_location()
{
$loader_path = false;
$ext_path = extension_dir_path();
if ($ext_path !== false) {
$id = $ext_path;
$here = dirname(__FILE__);
if (isset($id[1]) && $id[1] == ':') {
$id = str_replace('\\','/',substr($id,2));
$here = str_replace('\\','/',substr($here,2));
}
$rd=str_repeat('/..',substr_count($id,'/')).$here.'/';
$i=strlen($rd);
$loader_loc = DIRECTORY_SEPARATOR . basename($here) . DIRECTORY_SEPARATOR . get_loader_name();
while($i--) {
if($rd[$i]=='/') {
$loader_path = runtime_location_exists($ext_path,$rd,$i,$loader_loc);
if ($loader_path !== false) {
break;
}
}
}
if (!$loader_path && !empty($loader_loc) && @file_exists($loader_loc)) {
$loader_path = basename($loader_loc);
}
}
return $loader_path;
}
function runtime_location_exists($ext_dir,$path_str,$sep_pos,$loc_name)
{
$sub_path = substr($path_str,0,$sep_pos);
$lp = $sub_path . $loc_name;
$fqlp = $ext_dir.$lp;
if(@file_exists($fqlp)) {
return $lp;
} else {
return false;
}
}
function runtime_loading_is_possible() {
return !((is_php_version_or_greater(5,2,5)) || is_restricted_server() || !ini_get('enable_dl') || !function_exists('dl') || function_is_disabled('dl') || threaded_and_not_cgi());
}
function shared_and_runtime_loading()
{
return (find_server_type() == SERVER_SHARED && empty($_SESSION['use_ini_method']) && runtime_loading_is_possible());
}
function get_valid_runtime_loading_path($ignore_loading_check = false)
{
if ($ignore_loading_check || runtime_loading_is_possible()) {
return runtime_loader_location();
} else {
return false;
}
}
function runtime_loading($rtl_path = null)
{
if (empty($rtl_path)) {
$rtl_path = get_valid_runtime_loading_path();
}
if (!empty($rtl_path) && @dl($rtl_path)) {
return $rtl_path;
} else {
return false;
}
}
function get_runtime_loading_path_if_applicable()
{
$rtl = null;
if (shared_and_runtime_loading()) {
$rtl = get_valid_runtime_loading_path();
}
return $rtl;
}
function try_runtime_loading_if_applicable()
{
$rtl_path = get_runtime_loading_path_if_applicable();
if (!empty($rtl_path)) {
return runtime_loading($rtl_path);
} else {
return $rtl_path;
}
}
function runtime_loading_instructions()
{
$default = get_default_address();
echo '<h4>Runtime Loading Instructions</h4>';
echo '<div class=panel>';
echo '<p>On your shared server the Loader can be installed using the runtime loading method.';
echo " (<a href=\"{$default}&manual=1\">Please click here if you are <strong>not</strong> on a shared server</a>.)</p>";
if ('.' == extension_dir()) {
$dirphrase = is_ms_windows()?'folder':'directory';
echo "Please note that on your system the Loader <em>must</em> be present in the same " . $dirphrase . " as the first encoded file accessed.";
}
echo '<ol>';
loader_download_instructions();
$loader_dir = loader_install_instructions(SERVER_SHARED,dirname(__FILE__));
shared_test_instructions();
echo '</ol>';
echo '</div>';
}
function runtime_loading_errors()
{
$errors = array();
$ext_path = extension_dir_path();
if (false === $ext_path) {
$errors[ERROR_RUNTIME_EXT_DIR_NOT_FOUND] = "Extensions directory cannot be found.";
} else {
$expected_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . get_loader_name();
if (!@file_exists($expected_file)) {
$errors[ERROR_RUNTIME_LOADER_FILE_NOT_FOUND] = "The Loader file was expected to be at $expected_file but could not be found.";
} else {
$errors = loader_compatibility_test($expected_file);
}
}
return $errors;
}
function windows_package_name()
{
$sys = get_sysinfo();
$loader = get_loaderinfo();
return (LOADERS_PACKAGE_PREFIX . 'win' . '_' . ($sys['THREAD_SAFE']?'':'nonts_') . strtolower($sys['PHP_COMPILER']) . '_' . $loader['arch']);
}
function unix_package_name()
{
$sysinfo = get_sysinfo();
$loader = get_loaderinfo();
$multiple_os_versions = false;
if (is_array($loader) && array_key_exists('osvariants',$loader) && is_array($loader['osvariants'])) {
$versions = array_values($loader['osvariants']);
$multiple_os_versions = !empty($versions[0]);
}
if ($multiple_os_versions) {
list($reqd_version,$exact_match) = get_reqd_version($loader['osvariants']);
if ($reqd_version) {
$basename = LOADERS_PACKAGE_PREFIX . $loader['oscode'] . '_' . $reqd_version . '_' . $loader['arch'];
} else {
$basename = "";
}
} else {
$basename = LOADERS_PACKAGE_PREFIX . $loader['oscode'] . '_' . $loader['arch'];
}
return array($basename,$multiple_os_versions);
}
function loader_download_instructions()
{
$sysinfo = get_sysinfo();
$loader = get_loaderinfo();
$multiple_os_versions = false;
if (is_ms_windows()) {
if (is_bool($sysinfo['THREAD_SAFE'])) {
$download_str = '<li>Download the following archive of Windows ' . $sysinfo['PHP_COMPILER'];
if (!$sysinfo['THREAD_SAFE']) {
$download_str .= ' non-TS';
}
$download_str .= ' ' . $loader['arch'] . ' Loaders:';
echo $download_str;
$basename = windows_package_name();
echo make_archive_list($basename,array('zip'));
echo 'A Loaders archive can also be downloaded from <a href="' . LOADERS_PAGE . '" target="loaders">' . LOADERS_PAGE . '</a>.';
} else {
echo '<li>Download a Windows Loaders archive from <a href="' . LOADERS_PAGE . '" target=loaders>here</a>. If PHP is built with thread safety disabled, use the Windows non-TS Loaders.';
}
} else {
list($basename,$multiple_os_versions) = unix_package_name();
if ($basename == "") {
echo '<li>Download a ' . $loader['osname'] . ' ' . $loader['arch'] . ' Loaders archive from <a href="' . LOADERS_PAGE . '" target="loaders">here</a>.';
echo "<br>Your system appears to be {$loader['osnamequal']} for {$loader['wordsize']} bit. If Loaders are not available for that exact release of {$loader['osname']}, Loaders built for an earlier release should work. Note that you may need to install back compatibility libraries for the operating system.";
echo '<br>If you cannot find a suitable loader then please raise a ticket at <a href="'. SUPPORT_SITE . '">our support helpdesk</a>.';
} else {
echo '<li>Download one of the following archives of Loaders for ' . $loader['osnamequal'] . ' ' . $loader['arch'] . ':';
if (SERVER_SHARED == find_server_type()) {
$archives = array('zip','tar.gz');
} else {
$archives = array('tar.gz','zip');
}
echo make_archive_list($basename,$archives);
echo "</p>";
if ($multiple_os_versions && !$exact_match) {
echo "<p>Note that you may need to install back compatibility libraries for {$loader['osname']}.</p>";
}
}
}
echo '</li>';
}
function ini_dir()
{
$sysinfo = get_sysinfo();
$parent_dir = '';
if (!empty($sysinfo['PHP_INI'])) {
$parent_dir = dirname($sysinfo['PHP_INI']);
} else {
$parent_dir = $_SERVER["PHPRC"];
if (@is_file($parent_dir)) {
$parent_dir = dirname($parent_dir);
}
}
return $parent_dir;
}
function unix_install_dir()
{
$ext_dir = extension_dir_path();
$cur_dir = @realpath('.');
if (empty($ext_dir) || $ext_dir == $cur_dir) {
$loader_dir = UNIX_SYSTEM_LOADER_DIR;
} else {
$loader_dir = $ext_dir;
}
return $loader_dir;
}
function windows_install_dir()
{
$sysinfo = get_sysinfo();
if ($sysinfo['SS'] == 'IIS') {
if (false === ($ext_dir = extension_dir_path())) {
$parent_dir = ini_dir();
$ext_dir = $parent_dir . '\\ext';
if (!empty($parent_dir) && @file_exists($ext_dir)) {
$loader_dir = $ext_dir;
} else {
$loader_dir = $_SERVER['windir'] . '\\' . WINDOWS_IIS_LOADER_DIR;
}
} else {
$loader_dir = $ext_dir;
}
} else {
if (false === ($ext_dir = extension_dir_path())) {
$parent_dir = ini_dir();
$loader_dir = $parent_dir . '\\' . 'ioncube';
} else {
$loader_dir = $ext_dir;
}
}
return $loader_dir;
}
function loader_install_dir($server_type)
{
if (SERVER_SHARED == $server_type && own_php_ini_possible()) {
$loader_dir = get_default_loader_dir_webspace();
} elseif (is_ms_windows()) {
$loader_dir = windows_install_dir();
} else {
$loader_dir = unix_install_dir();
}
return $loader_dir;
}
function writeable_directories()
{
$root_path = @realpath($_SERVER['DOCUMENT_ROOT']);
$above_root_path = @realpath($_SERVER['DOCUMENT_ROOT'] . "/..");
$root_path_cgi_bin = @realpath($_SERVER['DOCUMENT_ROOT'] . "/cgi-bin");
$above_root_cgi_bin = @realpath($_SERVER['DOCUMENT_ROOT'] . "/../cgi-bin");
$paths = array();
foreach (array($root_path,$above_root_path,$root_path_cgi_bin,$above_root_cgi_bin) as $p) {
if (@is_writeable($p)) {
$paths[] = $p;
}
}
return $paths;
}
function loader_install_instructions($server_type,$loader_dir = '')
{
if (empty($loader_dir)) {
$loader_dir = loader_install_dir($server_type);
}
if (SERVER_LOCAL == $server_type) {
echo "<li>Put the Loader files in <code>$loader_dir</code></li>";
} else {
echo "<li>Transfer the Loaders to your web server and install in <code>$loader_dir</code></li>";
}
return $loader_dir;
}
function zend_extension_lines($loader_dir)
{
$zend_extension_lines = array();
$sysinfo = get_sysinfo();
$qt = (is_ms_windows()?'"':'');
$loader = get_loaderinfo();
if (!is_bool($sysinfo['THREAD_SAFE']) || !$sysinfo['THREAD_SAFE']) {
$path = $qt . $loader_dir . DIRECTORY_SEPARATOR . $loader['file'] . $qt;
$zend_extension_lines[] = "zend_extension = " . $path;
}
if ((!is_bool($sysinfo['THREAD_SAFE']) && !is_php_version_or_greater(5,3)) || $sysinfo['THREAD_SAFE']) {
$line_start = is_php_version_or_greater(5,3)?'zend_extension':'zend_extension_ts';
$path = $qt . $loader_dir . DIRECTORY_SEPARATOR . $loader['file_ts'] . $qt;
$zend_extension_lines[] = $line_start . " = " . $path;
}
return $zend_extension_lines;
}
function user_ini_base()
{
$doc_root_path = realpath($_SERVER['DOCUMENT_ROOT']);
$above_root_path = @realpath($_SERVER['DOCUMENT_ROOT'] . "/..");
if (!empty($above_root_path) && @is_writeable($above_root_path)) {
$start_path = $above_root_path;
} else {
$start_path = $doc_root_path;
}
return $start_path;
}
function user_ini_space_path($file)
{
$user_base = user_ini_base();
$fpath = @realpath($file);
if (!empty($fpath) && (0 === strpos($fpath,$user_base))) {
return $fpath;
} else {
return false;
}
}
function default_ini_path()
{
return (realpath($_SERVER['DOCUMENT_ROOT']));
}
function shared_ini_location()
{
$phprc = getenv('PHPRC');
if (!empty($phprc)) {
$phprc_path = user_ini_space_path($phprc);
if (false !== $phprc_path) {
return $phprc_path;
} else {
return default_ini_path();
}
} else {
return default_ini_path();
}
}
function zend_extension_instructions($server_type,$loader_dir)
{
$sysinfo = get_sysinfo();
$base = get_base_address();
$editing_ini = true;
$php_ini_name = ini_file_name();
if (isset($sysinfo['PHP_INI']) && @file_exists($sysinfo['PHP_INI'])) {
$php_ini_path = $sysinfo['PHP_INI'];
} else {
$php_ini_path = '';
}
if (is_bool($sysinfo['THREAD_SAFE'])) {
$kwd = zend_extension_line_start();
} else {
$kwd = 'zend_extension/zend_extension_ts';
}
$server_type_code = server_type_code();
$zend_extension_lines = zend_extension_lines($loader_dir);
if (SERVER_SHARED == $server_type && own_php_ini_possible()) {
$ini_dir = shared_ini_location();
$php_ini_path = $ini_dir . DIRECTORY_SEPARATOR . $php_ini_name;
if (@file_exists($php_ini_path)) {
$edit_line = "<li>Edit the <code>$php_ini_name</code> in the <code>$ini_dir</code> directory";
if (zend_extension_line_missing($php_ini_path) && @is_writeable($php_ini_path) && @is_writeable($ini_dir)) {
if (function_exists('file_get_contents')) {
$ini_strs = @file_get_contents($php_ini_path);
} else {
$lines = @file($php_ini_path);
$ini_strs = join(' ',$lines);
}
$fh = @fopen($php_ini_path,"wb");
if ($fh !== false) {
foreach ($zend_extension_lines as $zl) {
fwrite($fh,$zl . PHP_EOL);
}
fwrite($fh,$ini_strs);
fclose($fh);
$editing_ini = false;
echo "<li>Your php.ini file at $php_ini_path has been modified to include the necessary line for the ionCube Loader.";
} else {
echo $edit_line;
}
} else {
echo $edit_line;
}
} else {
$download_ini_file = "<li><a href=\"$base&page=phpconfig&ininame=$php_ini_name&stype=$server_type_code&download=1&prepend=1\">Save this <code>$php_ini_name</code> file</a> and upload it to <code>$ini_dir</code> (full path on your server).";
if (@is_writeable($ini_dir)) {
$fh = @fopen($php_ini_path,"wb");
if ($fh !== false) {
foreach ($zend_extension_lines as $zl) {
fwrite($fh,$zl . PHP_EOL);
}
if (!empty($sysinfo['PHP_INI']) && is_readable($sysinfo['PHP_INI'])) {
if (function_exists('file_get_contents')) {
$ini_strs = @file_get_contents($sysinfo['PHP_INI']);
} else {
$lines = @file($sysinfo['PHP_INI']);
$ini_strs = join(' ',$lines);
}
fwrite($fh,$ini_strs);
}
fclose($fh);
echo "<li>A <code>$php_ini_name</code> file has been created for you in <code>$ini_dir</code>.";
} else {
echo $download_ini_file;
}
} else {
echo $download_ini_file;
}
$editing_ini = false;
}
} elseif (!empty($sysinfo['PHP_INI'])) {
if (empty($sysinfo['PHP_INI_DIR'])) {
echo "<li>Edit the file <code>{$sysinfo['PHP_INI']}</code>";
} else {
$php_ini_path = find_additional_ioncube_ini();
if (empty($php_ini_path)) {
$php_ini_name = ADDITIONAL_INI_FILE_NAME;
echo "<li><a href=\"$base&page=phpconfig&download=1&newlinesonly=1&ininame=$php_ini_name&stype=$server_type_code\">Save this $php_ini_name file</a> and put it in your ini files directory, <code>{$sysinfo['PHP_INI_DIR']}</code>";
$editing_ini = false;
} else {
$php_ini_name = basename($php_ini_path);
echo "<li>Edit the file <code>$php_ini_path</code>";
}
}
} else {
echo "<li>Edit the system <code>$php_ini_name</code> file";
}
if ($editing_ini) {
echo " and <b>before</b> any other $kwd lines ensure that the following is included:<br>";
foreach ($zend_extension_lines as $zl) {
echo "<code>$zl</code><br>";
}
if (!empty($php_ini_path)) {
if (zend_extension_line_missing($php_ini_path)) {
echo "<a>Alternatively, replace your current <code>$php_ini_path</code> file with <a href=\"$base&page=phpconfig&ininame=$php_ini_name&stype=$server_type_code&download=1&prepend=1\">this new $php_ini_name file</a>.";
}
}
}
echo '</li>';
}
function server_restart_instructions()
{
$sysinfo = get_sysinfo();
$base = get_base_address();
if ($sysinfo['SS']) {
if ($sysinfo['SS'] == 'PHP-FPM') {
echo "<li>Restart PHP-FPM.</li>";
} else {
echo "<li>Restart the {$sysinfo['SS']} server software.</li>";
}
} else {
echo "<li>Restart the server software.</li>";
}
echo "<li>When the server software has restarted, <a href=\"$base&page=loader_check\" onclick=\"showOverlay();\">click here to test the Loader</a>.</li>";
if ($sysinfo['SS'] && $sysinfo['SS'] == 'PHP-FPM') {
echo '<li>If the Loader installation failed, check the PHP-FPM error log file for errors.</li>';
} elseif ($sysinfo['SS'] == 'Apache' && !is_ms_windows()) {
echo '<li>If the Loader installation failed, check the Apache error log file for errors and see our guide to <a target="unix_errors" href="'. UNIX_ERRORS_URL . '">Unix related errors</a>.</li>';
}
}
function shared_test_instructions()
{
$base = get_base_address();
echo "<li><a href=\"$base&page=loader_check\" onclick=\"showOverlay();\">Click here to test the Loader</a>.</li>";
}
function link_to_php_ini_instructions()
{
$default = get_default_address();
echo "<p><a href=\"{$default}&stype=s&ini=1\">Please click here for instructions on using the php.ini method instead</a>.</p>";
}
function php_ini_instruction_list($server_type)
{
echo '<h4>Installation Instructions</h4>';
echo '<div class=panel>';
echo '<ol>';
loader_download_instructions();
$loader_dir = loader_install_instructions($server_type);
zend_extension_instructions($server_type,$loader_dir);
if ($server_type != SERVER_SHARED || !own_php_ini_possible()) {
server_restart_instructions();
} else {
shared_test_instructions();
}
echo '</ol>';
echo '</div>';
}
function php_ini_install_shared($give_preamble = true)
{
$php_ini_name = ini_file_name();
$default = get_default_address();
if ($give_preamble) {
echo "<p>On your <strong>shared</strong> server, the Loader should be installed using a <code>$php_ini_name</code> configuration file.";
echo " (<a href=\"{$default}&manual=1\">Please click here if you are <strong>not</strong> on a shared server</a>.)</p>";
}
if (own_php_ini_possible()) {
echo '<p>With your hosting account, you may be able to use your own PHP configuration file.</p>';
} else {
echo "<p>It appears that you cannot install the ionCube Loader using the <code>$php_ini_name</code> file. Your server provider or system administrator should be able to perform the installation for you. Please refer them to the following instructions.</p>";
}
php_ini_instruction_list(SERVER_SHARED);
}
function php_ini_install($server_type_desc = null, $server_type = SERVER_DEDICATED, $required = true)
{
$php_ini_name = ini_file_name();
$default = get_default_address();
echo '<p>';
if ($server_type_desc) {
echo "For a <strong>$server_type_desc</strong> server ";
} else {
echo "For this server ";
}
if ($required) {
echo "you should install the ionCube Loader using the <code>$php_ini_name</code> configuration file.";
} else {
echo "installing the ionCube Loader using the <code>$php_ini_name</code> file is recommended.";
}
if ($server_type_desc) {
echo " (<a href=\"{$default}&manual=1\">Please click here if you are <strong>not</strong> on a $server_type_desc server</a>.)";
}
echo '</p>';
php_ini_instruction_list($server_type);
}
function help_resources($error_list = array())
{
$self = get_self();
$base = get_base_address();
$server_type_code = server_type_code();
$server_type = find_server_type();
$sysinfo = get_sysinfo();
$resources = array(
'<a target="_blank" href="' . LOADERS_FAQ_URL . '">ionCube Loaders FAQ</a>',
'<a target="_blank" href="' . LOADER_FORUM_URL . '">ionCube Loader Forum</a>'
);
if (SERVER_SHARED != $server_type || own_php_ini_possible(true)) {
$support_info = array (
'department' => WIZARD_SUPPORT_TICKET_DEPARTMENT,
'subject' => "ionCube Loader installation problem",
'message' => support_ticket_information()
);
if (SERVER_LOCAL == $server_type && !info_should_be_disabled()) {
$temp_files = system_info_temporary_files();
} else {
$temp_files = NULL;
}
if (!empty($temp_files)) {
$support_info['ini'] = base64_encode(file_get_contents($temp_files['ini']));
$support_info['phpinfo'] = base64_encode(file_get_contents($temp_files['phpinfo']));
$support_info['additional'] = base64_encode(file_get_contents($temp_files['additional']));
$loader_path = find_loader(true);
if (is_string($loader_path)) {
$support_info['loader'] = base64_encode(file_get_contents($loader_path));
$support_info['loader_name'] = basename($loader_path);
} else {
$support_info['loader'] = '';
$support_info['loader_name'] = '';
}
} else {
$support_info['ini'] = '';
$support_info['phpinfo'] = '';
$support_info['additional'] = '';
$support_info['loader'] = '';
$support_info['loader_name'] = '';
}
$resources[2] = '<form action="' . SUPPORT_SITE . 'lw_index.php' .'" method="POST" id="support-ticket"><a href="" onclick="document.getElementById(\'support-ticket\').submit(); return false;">Raise a support ticket through our helpdesk</a>';
$resources[2] .= '<input type="hidden" name="department" value="' . $support_info['department'] . '"/>';
$resources[2] .= '<input type="hidden" name="subject" value="' . $support_info['subject'] . '"/>';
$resources[2] .= '<input type="hidden" name="message" value="' . $support_info['message'] . '"/>';
if (!empty($temp_files)) {
$resources[2] .= '<input type="hidden" name="phpinfo" value="' . $support_info['phpinfo'] . '"/>';
$resources[2] .= '<input type="hidden" name="ini" value="' . $support_info['ini'] . '"/>';
$resources[2] .= '<input type="hidden" name="additional" value="' . $support_info['additional'] . '"/>';
$resources[2] .= '<input type="hidden" name="loader" value="' . $support_info['loader'] . '"/>';
$resources[2] .= '<input type="hidden" name="loader_name" value="' . $support_info['loader_name'] . '"/>';
}
$resources[2] .= '</form>';
}
if (SERVER_SHARED == $server_type && own_php_ini_possible(true) && !user_ini_space_path($sysinfo['PHP_INI'])) {
$resources[3] = '<strong>Please check with your host that you can create php.ini files that will override the system one.</strong>';
}
return $resources;
}
function system_info_temporary_files()
{
$tmpfname_ini = get_tempnam("/tmp", "INI");
$tmpfname_ini .= ".ini";
$fh_ini = @fopen($tmpfname_ini,'wb');
if ($fh_ini) {
$config = all_ini_contents();
fwrite($fh_ini,$config);
fclose($fh_ini);
} else {
$tmpfname_ini = '';
}
$tmpfname_pinf = get_tempnam("/tmp", "PIN");
$tmpfname_pinf .= ".html";
$fh_pinfo = @fopen($tmpfname_pinf,'wb');
if ($fh_pinfo) {
ob_start();
@phpinfo();
$pinfo = ob_get_contents();
ob_end_clean();
fwrite($fh_pinfo,$pinfo);
fclose($fh_pinfo);
} else {
$tmpfname_pinf = '';
}
$tmpfname_add = get_tempnam("/tmp", "ADD");
$tmpfname_add .= ".html";
$fh_add = @fopen($tmpfname_add,'wb');
if ($fh_add) {
ob_start();
extra_page(false);
$extra = ob_get_contents();
ob_end_clean();
fwrite($fh_add,$extra);
fclose($fh_add);
} else {
$tmpfname_add = '';
}
if (empty($tmpfname_ini) || empty($tmpfname_pinf) || empty($tmpfname_add)) {
return (array());
} else {
return (array('ini' => $tmpfname_ini,
'phpinfo' => $tmpfname_pinf,
'additional' => $tmpfname_add));
}
}
function get_tempnam($default_tmp_dir = '', $prefix = '')
{
if (function_exists('sys_get_temp_dir')) {
return tempnam(sys_get_temp_dir(),$prefix);
} else {
return @tempnam($default_tmp_dir, $prefix);
}
}
function system_info_archive_page()
{
info_disabled_check();
$server_type = find_server_type();
if (SERVER_LOCAL != $server_type) {
exit;
}
$loader = find_loader(true);
if (is_string($loader)) {
$loader_file = $loader;
} else {
$loader_file = '';
}
$all_files = system_info_temporary_files();
if (!empty($all_files)) {
if (!empty($loader_file)) {
$all_files['loader'] = $loader_file;
}
$archive_name = get_tempnam('/tmp',"ARC");
if (extension_loaded('zip')) {
$archive_name .= '.zip';
$zip = @new ZipArchive();
$mode = @constant("ZIPARCHIVE::OVERWRITE");
if (!$zip || $zip->open($archive_name, $mode)!==TRUE) {
$archive_name = '';
} else {
foreach($all_files as $f) {
$zip->addFile($f,basename($f));
}
$zip->close();
}
} elseif (extension_loaded('zlib') && !is_ms_windows()) {
$tar_name = $archive_name . ".tar";
$all_files_str = join(' ',$all_files);
$script = "tar -chf $tar_name $all_files_str";
$result = @system($script,$retval);
if ($result !== false) {
$archive_name = $tar_name . '.gz';
$zp = gzopen($archive_name,"w9");
$tar_contents = get_file_contents($tar_name);
gzwrite($zp,$tar_contents);
gzclose($zp);
} else {
$archive_name = '';
}
} else {
$archive_name = '';
}
} else {
$archive_name = '';
}
if ($archive_name) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='. $archive_name);
@readfile($archive_name);
} else {
$self = get_self();
$base = get_base_address();
$server_type_code = server_type_code();
heading();
echo "<p>A downloadable archive of system information could not be created.<br>
<strong>Please save each of the following and then attach those files to the support ticket:</strong></p>";
echo "<ul>";
echo "<li><a href=\"$base&page=phpinfo\" target=\"phpinfo\">phpinfo()</a></li>";
echo "<li><a href=\"$base&page=phpconfig\" target=\"phpconfig\">config</a></li>";
echo "<li><a href=\"$base&page=extra&stype=$server_type_code\" target=\"extra\">additional information</a></li>";
echo "<li><a href=\"$self?page=loaderbin\">loader file</a></li>";
echo "</ul>";
footer(true);
}
}
function support_ticket_information($error_list = array())
{
$sys = get_sysinfo();
$ld = get_loaderinfo();
$ticket_strs = array();
$ticket_strs[] = "PLEASE DO NOT REMOVE THE FOLLOWING INFORMATION\r\n";
$ticket_strs[] = "==============\r\n";
if (!empty($error_list)) {
$ticket_strs[] = "[hr]";
$ticket_strs[] = "ERRORS";
$ticket_strs[] = "[table]";
$ticket_strs[] = '[tr][td]' . join('[/td][/tr][tr][td]',$error_list) . '[/td][/tr]';
$ticket_strs[] = "[/table]";
}
$ticket_strs[] = "[hr]";
$ticket_strs[] = "SYSTEM INFORMATION";
$info_lines = array();
$info_lines["Wizard version"] = script_version();
$info_lines["PHP uname"] = $ld['uname'];
$info_lines["Machine architecture"] = $ld['arch'];
$info_lines["Word size"] = $ld['wordsize'];
$info_lines["Operating system"] = $ld['osname'] . ' ' . $ld['osver'];
if (selinux_is_enabled() || possibly_selinux()) {
$info_lines["Security enhancements"] = "SELinux";
} elseif (grsecurity_is_enabled()) {
$info_lines["Security enhancements"] = "Grsecurity";
} else {
$info_lines["Security enhancements"] = "None";
}
$info_lines["PHP version"] = PHP_VERSION;
if ($sys['DEBUG_BUILD']) {
$info_lines["DEBUG BUILD"] = "DEBUG BUILD OF PHP";
}
if (!$sys['SUPPORTED_COMPILER']) {
$info_lines["SUPPORTED PHP COMPILER"] = "FALSE";
$info_lines["PHP COMPILER"] = $sys['PHP_COMPILER'];
}
$info_lines["Is CLI?"] = ($sys['IS_CLI']?"Yes":"No");
$info_lines["Is CGI?"] = ($sys['IS_CGI']?"Yes":"No");
$info_lines["Is thread-safe?"] = ($sys['THREAD_SAFE']?"Yes":"No");
$info_lines["Web server"] = $sys['FULL_SS'];
$info_lines["Server type"] = server_type_string();
$info_lines["PHP ini file"] = $sys['PHP_INI'];
if (!@file_exists($sys['PHP_INI'])) {
$info_lines["Ini file found"] = "INI FILE NOT FOUND";
} else {
if (is_readable($sys['PHP_INI'])) {
$info_lines["Ini file found"] = "INI FILE READABLE";
} else {
$fh = @fopen($sys['PHP_INI'],"rb");
if ($fh === false) {
$info_lines["Ini file found"] = "INI FILE FOUND BUT POSSIBLY NOT READABLE";
} else {
$info_lines["Ini file found"] = "INI FILE READABLE";
}
}
}
$info_lines["PHPRC"] = $sys['PHPRC'];
$loader_path = find_loader();
if (is_string($loader_path)) {
$info_lines["Loader path"] = $loader_path;
$info_lines["Loader file size"] = filesize($loader_path) . " bytes.";
$info_lines["Loader MD5 sum"] = md5_file($loader_path);
} else {
$info_lines["Loader path"] = "LOADER PATH NOT FOUND";
}
$server_type_code = server_type_code();
if (!empty($_SESSION['hostprovider'])) {
$info_lines['Hosting provider'] = $_SESSION['hostprovider'];
$info_lines['Provider URL'] = $_SESSION['hosturl'];
}
$info_lines["Wizard script path"] = '[url]http://' . $_SERVER["HTTP_HOST"] . get_self() . '?stype='. $server_type_code . '[/url]';
$ticket_strs[] = "[table]";
foreach ($info_lines as $h => $i) {
$value = (empty($i))?'EMPTY':$i;
$ticket_strs[] = '[tr][td]' . $h . '[/td]' . '[td]' . $value . '[/td][/tr]';
}
$ticket_strs[] = '[/table]';
$ticket_strs[] = '[hr]';
$ticket_strs[] = "\r\n==============\r\n";
$ticket_strs[] = "PLEASE ENTER ANY ADDITIONAL INFORMATION BELOW\r\n";
$support_ticket_str = join('',$ticket_strs);
return urlencode($support_ticket_str);
}
function wizard_stats_data($page_id)
{
$data = array();
try_runtime_loading_if_applicable();
$sysinfo = get_sysinfo();
$ldinfo = get_loaderinfo();
$data['sessionid'] = session_id();
$data['wizard_version'] = script_version();
$data['server_type'] = server_type_code();
$data['hostprovider'] = (isset($_SESSION['hostprovider']))?$_SESSION['hostprovider']:'';
$data['hosturl'] = (isset($_SESSION['hosturl']))?$_SESSION['hosturl']:'';
$data['page_id'] = $page_id;
$data['loader_state'] = (extension_loaded(LOADER_EXTENSION_NAME))?'installed':'failure';
$data['ini_location'] = $sysinfo['PHP_INI'];
$data['is_cgi'] = ($sysinfo['IS_CGI'])?"yes":"no";
$data['is_ts'] = ($sysinfo['THREAD_SAFE'])?"yes":"no";
$data['arch'] = $ldinfo['arch'];
$data['php_version'] = PHP_VERSION;
$data['os'] = $ldinfo['osname'];
$data['word_size'] = $ldinfo['wordsize'];
$data['referrer'] = $_SERVER["HTTP_HOST"] . get_self();
return $data;
}
function send_stats($page_id = 'default')
{
$server_type = find_server_type();
$res = false;
if (SERVER_LOCAL != $server_type) {
$stats_data = wizard_stats_data($page_id);
if (!isset($_SESSION['stats_sent'][$page_id][$stats_data['loader_state']])) {
$url = WIZARD_STATS_URL;
if (!empty($stats_data)) {
if(function_exists('http_build_query')) {
$qparams = http_build_query($stats_data);
} else {
$qparams = php4_http_build_query($stats_data);
}
$url .= '?' . $qparams;
$res = remote_file_contents($url);
}
$_SESSION['stats_sent'][$page_id][$stats_data['loader_state']] = 1;
} else {
$res = true;
}
} else {
$res = 'LOCAL';
}
return $res;
}
function os_arch_string_check($loader_str)
{
$errors = array();
if (preg_match("/target os:\s*(([^_]+)_([^-]*)-([[:graph:]]*))/i",$loader_str,$os_matches)) {
$loader_info = get_loaderinfo();
$dirname = calc_dirname();
$packed_osname = preg_replace('/\s/','',strtolower($loader_info['osname']));
if (strtolower($dirname) != $os_matches[1] && $packed_osname != $os_matches[2]) {
$errors[ERROR_LOADER_WRONG_OS] = "You have the wrong loader for your operating system, ". $loader_info['osname'] . ".";
} else {
$loader_wordsize = (strpos($os_matches[3],'64') === false)?32:64;
if ($loader_info['arch'] != ($ap = required_loader_arch($os_matches[3],$loader_info['oscode'],$loader_wordsize))) {
$err_str = "You have the wrong loader for your machine architecture.";
$err_str .= " Your system is " . $loader_info['arch'];
$err_str .= " but the loader you are using is for " . $ap . ".";
$errors[ERROR_LOADER_WRONG_ARCH] = $err_str;
}
}
}
return $errors;
}
function get_loader_strings($loader_location)
{
if (function_exists('file_get_contents')) {
$loader_strs = @file_get_contents($loader_location);
} else {
$lines = @file($loader_location);
$loader_strs = join(' ',$lines);
}
return $loader_strs;
}
function loader_system($loader_location)
{
$loader_system = array();
$loader_strs = get_loader_strings($loader_location);
if (!empty($loader_strs)) {
if (preg_match("/ioncube_loader_..?\.._(.)\.(.)\.(..?)(_nonts)?(_amd64)?\.dll/i",$loader_strs,$version_matches)) {
$loader_system['oscode'] = 'win';
$loader_system['thread_safe'] = (isset($version_matches[4]) && $version_matches[4] == '_nonts')?0:1;
if (preg_match("/_localtime([0-9][0-9])/i",$loader_strs,$size_matches)) {
$loader_system['wordsize'] = ($size_matches[1] == '64')?64:32;
} else {
$loader_system['wordsize'] = 32;
}
$loader_system['arch'] = ($loader_system['wordsize'] == 64)?'x86-64':'x86';
$loader_system['php_version_major'] = $version_matches[1];
$loader_system['php_version_minor'] = $version_matches[2];
if ($loader_system['php_version_major'] == 8 && $loader_system['php_version_minor'] >= 1) {
$loader_system['compiler'] = 'VC16';
} elseif ($loader_system['php_version_major'] == 7 && $loader_system['php_version_minor'] >= 2) {
$loader_system['compiler'] = 'VC15';
} elseif ($loader_system['php_version_major'] == 7 && $loader_system['php_version_minor'] < 2) {
$loader_system['compiler'] = 'VC14';
} elseif ($loader_system['php_version_major'] == 5 && $loader_system['php_version_minor'] >= 5) {
$loader_system['compiler'] = 'VC11';
} elseif (preg_match("/assemblyIdentity.*version=\"([^.]+)\./",$loader_strs,$compiler_matches)) {
$loader_system['compiler'] = "VC" . strtoupper($compiler_matches[1]);
} else {
$loader_system['compiler'] = 'VC6';
}
} elseif (preg_match("/php version:\s*(.)\.(.)\.(..?)(-ts)?/i",$loader_strs,$version_matches)) {
$loader_system['thread_safe'] = (isset($version_matches[4]) && $version_matches[4] == '-ts')?1:0;
$loader_system['php_version_major'] = $version_matches[1];
$loader_system['php_version_minor'] = $version_matches[2];
if (preg_match("/target os:\s*(([^_]+)_([^-]*)-([[:graph:]]*))/i",$loader_strs,$os_matches)) {
$loader_system['oscode'] = strtolower(substr($os_matches[2],0,3));
$loader_system['wordsize'] = (strpos($os_matches[3],'64') === false)?32:64;
$loader_system['arch'] = required_loader_arch($os_matches[3],$loader_system['oscode'],$loader_system['wordsize']);
$loader_system['compiler'] = $os_matches[4];
}
}
if (preg_match("/ionCube Loader Version\s+(\S+)/",$loader_strs,$loader_version)) {
$loader_system['loader_version'] = $loader_version[1];
} elseif (preg_match("/ioncube_loader_(\d{1,2}\.\d\.\d{1,2})\./",$loader_strs,$loader_version)){
$loader_system['loader_version'] = $loader_version[1];
} else {
$loader_system['loader_version'] = 'UNKNOWN';
}
if (isset($loader_system['php_version_major'])) {
$loader_system['php_version'] = $loader_system['php_version_major'] . '.' . $loader_system['php_version_minor'];
}
}
return $loader_system;
}
function loader_compatibility_test($loader_location)
{
$errors = array();
$sysinfo = get_sysinfo();
if (LOADER_NAME_CHECK) {
$installed_loader_name = basename($loader_location);
$expected_loader_name = get_loader_name();
if ($installed_loader_name != $expected_loader_name) {
$errors[ERROR_LOADER_UNEXPECTED_NAME] = "The installed loader (<code>$installed_loader_name</code>) does not have the name expected (<code>$expected_loader_name</code>) for your system. Please check that you have the correct loader for your system.";
}
}
if (empty($errors) && !is_readable($loader_location)) {
$execute_error = "The loader at $loader_location does not appear to be readable.";
$execute_error .= "<br>Please check that it exists and is readable.";
$execute_error .= "<br>Please also check the permissions of the containing ";
$execute_error .= (is_ms_windows()?'folder':'directory') . '.';
if ($sysinfo['SS'] == 'PHP-FPM') {
$execute_error .= "<br>Please also check that PHP-FPM has been restarted.";
} elseif (($sysinfo['SS'] == 'IIS') || !($sysinfo['IS_CGI'] || $sysinfo['IS_CLI'])) {
$execute_error .= "<br>Please also check that the web server has been restarted.";
}
$execute_error .= ".";
$errors[ERROR_LOADER_NOT_READABLE] = $execute_error;
}
$loader_strs = get_loader_strings($loader_location);
$phpv = php_version();
if (preg_match("/php version:\s*(.)\.(.)\.(..?)(-ts)?/i",$loader_strs,$version_matches)) {
if ($version_matches[1] != $phpv['major'] || $version_matches[2] != $phpv['minor']) {
$loader_php = $version_matches[1] . "." . $version_matches[2];
$server_php = $phpv['major'] . "." . $phpv['minor'];
$errors[ERROR_LOADER_PHP_MISMATCH] = "The installed loader is for PHP $loader_php but your server is running PHP $server_php.";
}
if (is_bool($sysinfo['THREAD_SAFE']) && $sysinfo['THREAD_SAFE'] && !is_ms_windows() && !(isset($version_matches[4]) && $version_matches[4] == '-ts')) {
$errors[ERROR_LOADER_NONTS_PHP_TS] = "Your server is running a thread-safe version of PHP but the loader is not a thread-safe version.";
} elseif (isset($version_matches[4]) && $version_matches[4] == '-ts' && !(is_bool($sysinfo['THREAD_SAFE']) && $sysinfo['THREAD_SAFE'])) {
$errors[ERROR_LOADER_TS_PHP_NONTS] = "Your server is running a non-thread-safe version of PHP but the loader is a thread-safe version.";
}
} elseif (preg_match("/ioncube_loader_..?\.._(.)\.(.)\.(..?)(_nonts)?(_amd64)?\.dll/i",$loader_strs,$version_matches)) {
if (!is_ms_windows()) {
$errors[ERROR_LOADER_WIN_SERVER_NONWIN] = "You have a Windows loader but your server does not appear to be running Windows.";
} else {
if (isset($version_matches[4]) && $version_matches[4] == '_nonts' && is_bool($sysinfo['THREAD_SAFE']) && $sysinfo['THREAD_SAFE']) {
$errors[ERROR_LOADER_WIN_NONTS_PHP_TS] = "You have the non-thread-safe version of the Windows loader but you need the thread-safe one.";
} elseif (!(is_bool($sysinfo['THREAD_SAFE']) && $sysinfo['THREAD_SAFE']) && !(isset($version_matches[4]) && $version_matches[4] == '_nonts')) {
$errors[ERROR_LOADER_WIN_TS_PHP_NONTS] = "You have the thread-safe version of the Windows loader but you need the non-thread-safe one.";
}
if ($version_matches[1] != $phpv['major'] || $version_matches[2] != $phpv['minor']) {
$loader_php = $version_matches[1] . "." . $version_matches[2];
$server_php = $phpv['major'] . "." . $phpv['minor'];
$errors[ERROR_LOADER_WIN_PHP_MISMATCH] = "The installed loader is for PHP $loader_php but your server is running PHP $server_php.";
}
if ($version_matches[1] == 8 && $version_matches[2] >= 1) {
$loader_compiler = 'VC16';
} elseif ($version_matches[1] == 7 && $version_matches[2] >= 2) {
$loader_compiler = 'VC15';
} elseif ($version_matches[1] == 7) {
$loader_compiler = 'VC14';
} elseif ($version_matches[1] == 5 && $version_matches[2] >= 5) {
$loader_compiler = 'VC11';
} elseif (preg_match("/assemblyIdentity.*version=\"([^.]+)\./",$loader_strs,$compiler_matches)) {
$loader_compiler = "VC" . strtoupper($compiler_matches[1]);
} else {
$loader_compiler = 'VC6';
}
if ($loader_compiler != $sysinfo['PHP_COMPILER']) {
$errors[ERROR_LOADER_WIN_COMPILER_MISMATCH] = "Your loader was built using $loader_compiler but you need the loader built using {$sysinfo['PHP_COMPILER']}.";
}
}
} else {
$errors[ERROR_LOADER_PHP_VERSION_UNKNOWN] = "The PHP version for the loader cannot be determined - please check that you have a valid ionCube Loader.";
}
$errors += os_arch_string_check($loader_strs);
return $errors;
}
function shared_server()
{
if (!$rtl_path = runtime_loading()) {
if (empty($_SESSION['use_ini_method']) && runtime_loading_is_possible()) {
runtime_loading_instructions();
} else {
php_ini_install_shared();
}
} else {
list($lv,$mv,$newer_version) = ioncube_loader_version_information();
$phpv = php_version_maj_min();
echo "<p>The ionCube Loader $lv for PHP $phpv has been successfully installed.</p>";
$is_legacy_loader = loader_major_version_instructions($mv);
if ($is_legacy_loader) {
loader_upgrade_instructions($lv,$newer_version);
}
successful_install_end_instructions($rtl_path);
}
}
function dedicated_server()
{
php_ini_install('dedicated or VPS', SERVER_DEDICATED, true);
}
function local_install()
{
php_ini_install('local',SERVER_LOCAL, true);
}
function unregister_globals()
{
if (!ini_get('register_globals')) {
return;
}
if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS'])) {
die('GLOBALS overwrite attempt detected');
}
$noUnset = array('GLOBALS', '_GET',
'_POST', '_COOKIE',
'_REQUEST', '_SERVER',
'_ENV', '_FILES');
$input = array_merge($_GET, $_POST,
$_COOKIE, $_SERVER,
$_ENV, $_FILES,
isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array());
foreach ($input as $k => $v) {
if (!in_array($k, $noUnset) && isset($GLOBALS[$k])) {
unset($GLOBALS[$k]);
}
}
}
function clear_session($persist = array())
{
$persist['not_go_daddy'] = empty($_SESSION['not_go_daddy'])?0:1;
$persist['use_ini_method'] = empty($_SESSION['use_ini_method'])?0:1;
$persist['server_type'] = empty($_SESSION['server_type'])?SERVER_UNKNOWN:$_SESSION['server_type'];
@session_destroy();
$_SESSION = array();
$_SESSION['CREATED'] = time();
$_SESSION = $persist;
}
function can_archive()
{
return (extension_loaded('zip') || (extension_loaded('zlib') && !is_ms_windows()));
}
function is_ioncube()
{
return (($_SERVER["REMOTE_ADDR"] == IONCUBE_IP_ADDRESS) || ($_SERVER["REMOTE_ADDR"] == gethostbyname(IONCUBE_ACCESS_ADDRESS)));
}
function can_reach_ioncube()
{
return (isset($_SESSION['remote_access_successful']));
}
function info_should_be_disabled($only_allow_ioncube = false)
{
$elapsed = time() - max(filemtime(__FILE__),filectime(__FILE__));
if (is_ioncube()) {
$cutoff_time = IONCUBE_WIZARD_EXPIRY_MINUTES * 60;
} else {
if (!$only_allow_ioncube && !extension_loaded(LOADER_EXTENSION_NAME)) {
$cutoff_time = WIZARD_EXPIRY_MINUTES * 60;
} else {
return true;
}
}
return ($elapsed > $cutoff_time);
}
function info_disabled_text()
{
return "The information you have tried to access has been disabled for security reasons. Please re-install this Loader Wizard script and try again.";
}
function info_disabled_check()
{
if (info_should_be_disabled()) {
heading();
echo info_disabled_text();
footer(true);
exit;
}
}
function run()
{
$user_agent = $_SERVER['HTTP_USER_AGENT'];
if (preg_match('/googlebot/i',$user_agent)) {
exit;
}
unregister_globals();
if (is_php_version_or_greater(4,3,0)) {
ini_set('session.use_only_cookies',1);
}
$session_ok = @session_start();
if (!defined('PHP_EOL')) {
if (is_ms_windows()) {
define('PHP_EOL',"\r\n");
} else {
define('PHP_EOL',"\n");
}
}
if (!isset($_SESSION['CREATED'])) {
$_SESSION['CREATED'] = time();
} elseif (time() - $_SESSION['CREATED'] > SESSION_LIFETIME_MINUTES * 60 ) {
clear_session();
}
if (!isset($_SERVER)) $_SERVER =& $HTTP_SERVER_VARS;
(php_sapi_name() == 'cli') && die("This script should only be run by a web server.\n");
$page = get_request_parameter('page');
$host = get_request_parameter('host');
$clear = get_request_parameter('clear');
$ini = get_request_parameter('ini');
$timeout = get_request_parameter('timeout');
if ($timeout) {
$_SESSION['timing_out'] = 1;
$_SESSION['initial_run'] = 0;
}
if (!empty($host)) {
if ($host == 'ngd') {
$_SESSION['not_go_daddy'] = 1;
}
}
if (!empty($ini)) {
$_SESSION['use_ini_method'] = 1;
}
if (!empty($clear)) {
clear_session();
unset($_SESSION['not_go_daddy']);
unset($_SESSION['use_ini_method']);
unset($_SESSION['server_type']);
} else {
$stype = get_request_parameter('stype');
$hostprovider = get_request_parameter('hostprovider');
$hosturl = get_request_parameter('hosturl');
if (!empty($hostprovider)) {
$_SESSION['hostprovider'] = $hostprovider;
$_SESSION['hosturl'] = $hosturl;
}
$server_type = find_server_type($stype,false,true);
}
if ($session_ok && !$timeout && !isset($_SESSION['initial_run']) && empty($page)) {
$_SESSION['initial_run'] = 1;
initial_page();
@session_write_close();
exit;
} else {
$_SESSION['initial_run'] = 0;
}
if (empty($_SESSION['server_type'])) {
$_SESSION['server_type'] = SERVER_UNKNOWN;
}
if (empty($page) || !function_exists($page . "_page")) {
$page = get_default_page();
}
$fn = "{$page}_page";
$fn();
@session_write_close();
exit(0);
}
function wizardversion_page()
{
$start_time = time();
$wizard_version_only = get_request_parameter('wizard_only');
$clear_session_info = get_request_parameter('clear_info');
if ($clear_session_info) {
unset($_SESSION['timing_out']);
unset($_SESSION['latest_wizard_version']);
}
$wizard_version = latest_wizard_version();
$message = '';
if (false === $wizard_version) {
$message = "0";
} elseif (update_is_available($wizard_version)) {
$message = "$wizard_version";
} else {
$message = "1";
}
echo $message;
@session_write_close();
exit(0);
}
function platforminfo_page()
{
$message = '';
$platforms = get_loader_platforms();
$message = empty($platforms)?0:1;
echo $message;
@session_write_close();
exit(0);
}
function loaderversion_page()
{
$message = '';
$loader_versions = get_loader_version_info();
$message = empty($loader_versions)?0:1;
echo $message;
@session_write_close();
exit(0);
}
function compilerversion_page()
{
$message = '';
$compiler_versions = find_win_compilers();
$message = empty($compiler_versions)?0:1;
echo $message;
@session_write_close();
exit(0);
}
function initial_page()
{
$self = get_self();
$start_page = get_default_address(false);
$stage_timeout = 7000;
$step_lag = 500;
echo <<<EOT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>ionCube Loader Wizard</title>
<link rel="stylesheet" type="text/css" href="$self?page=css">
<style type="text/css">
body {
height: 100%;
width: 100%;
}
</style>
<script type="text/javascript">
var timingOut = 0;
var xmlHttpTimeout;
var ajax;
var statusPar;
var stage_timeout = $stage_timeout;
var step_lag = $step_lag;
function checkNextStep(ajax,expected,continuation) {
if (ajax.readyState==4 && ajax.status==200)
{
clearTimeout(xmlHttpTimeout);
if (ajax.responseText == expected) {
setTimeout('',step_lag);
continuation();
} else {
statusPar.innerHTML = 'Unable to check for update<br>script continuing';
setTimeout("window.location.href = '$start_page&timeout=1'",1000);
}
}
}
function getXmlHttp() {
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
}
var startMainLoaderWizard = function() {
window.location.href = '$start_page';
}
var loaderVersionCheck = function() {
statusPar.innerHTML = 'Stage 4/4: Getting latest loader versions';
var xmlHttp = getXmlHttp();
xmlHttp.onreadystatechange=function() {
checkNextStep(xmlHttp,"1",startMainLoaderWizard);
}
xmlHttp.open("GET","$self?page=loaderversion",true);
xmlHttp.send("");
ajax = xmlHttp;
xmlHttpTimeout=setTimeout('ajaxTimeout()',stage_timeout);
}
var platformCheck = function() {
statusPar.innerHTML = 'Stage 3/4: Getting platform information';
var xmlHttp = getXmlHttp();
xmlHttp.onreadystatechange=function() {
checkNextStep(xmlHttp,"1",loaderVersionCheck);
}
xmlHttp.open("GET","$self?page=platforminfo",true);
xmlHttp.send("");
ajax = xmlHttp;
xmlHttpTimeout=setTimeout('ajaxTimeout()',stage_timeout);
}
var compilerVersionCheck = function() {
statusPar.innerHTML = 'Stage 2/4: Getting compiler versions';
var xmlHttp = getXmlHttp();
xmlHttp.onreadystatechange=function() {
checkNextStep(xmlHttp,"1",platformCheck);
}
xmlHttp.open("GET","$self?page=compilerversion",true);
xmlHttp.send("");
ajax = xmlHttp;
xmlHttpTimeout=setTimeout('ajaxTimeout()',stage_timeout);
}
var startChecks = function() {
statusPar = document.getElementById('status');
statusPar.innerHTML = 'Stage 1/4: Getting Loader Wizard version';
var xmlHttp = getXmlHttp();
xmlHttp.onreadystatechange=function() {
checkNextStep(xmlHttp,"1",compilerVersionCheck);
}
xmlHttp.open("GET","$self?page=wizardversion",true);
xmlHttp.send("");
ajax = xmlHttp;
xmlHttpTimeout=setTimeout('ajaxTimeout()',stage_timeout);
}
function ajaxTimeout(){
ajax.abort();
statusPar.innerHTML = 'Cannot reach server<br>script continuing';
setTimeout("window.location.href = '$start_page&timeout=1'",1000);
}
</script>
</head>
<body>
<div id="loading"><script type="text/javascript">document.write('<p>Initialising<br>ionCube Loader Wizard<br><span id="status"></span></p>');</script><p id="noscript">Your browser does not support JavaScript so the ionCube Loader Wizard initialisation cannot be made now. This script can get the latest loader version information from the ionCube server when you go to the next page.<br>Please choose one of the following. <br>If the script appears to hang please restart the script and choose the "NO" option.<br><br><br><a href="$start_page">YES - my server DOES have internet access</a><br><br><a href="$start_page&timeout=1">NO - my server does NOT have internet access</a></p></div>
<script type="text/javascript">
document.getElementById('noscript').style.display = 'none';
window.onload = startChecks;
</script>
</body>
</html>
EOT;
}
function default_page($loader_extension = LOADER_EXTENSION_NAME)
{
$self = get_self();
foreach (array('self') as $vn) {
if (empty($$vn)) {
$server_data = print_r($_SERVER,true);
error("Unable to initialise ($vn)". ' $_SERVER is: ' . $server_data);
}
}
heading();
$wizard_update = check_for_wizard_update(true);
$rtl = try_runtime_loading_if_applicable();
$server_type = find_server_type();
if (extension_loaded($loader_extension) && $server_type != SERVER_UNKNOWN) {
loader_already_installed($rtl);
} else {
loader_not_installed();
}
send_stats('default');
footer($wizard_update);
}
function uninstall_wizard_instructions()
{
echo '<p><strong>For security reasons we advise that you remove this Wizard script from your server now that the ionCube Loader is installed.</strong></p>';
}
function contact_script_provider_instructions()
{
echo '<p>Please contact the script provider if you do experience any problems running encoded files.</p>';
}
function may_need_to_copy_ini()
{
$sys = get_sysinfo();
if (ini_same_dir_as_wizard() && $sys['IS_CGI']) {
$dirphrase = is_ms_windows()?'folder':'directory';
$ini = ini_file_name();
echo "<p>Please note that if encoded files in a different $dirphrase from the Wizard fail then you should attempt to copy the $ini file to each $dirphrase in which you have encoded files.</p>";
}
}
function ioncube_24_is_available()
{
$loaderinfo = get_loaderinfo();
$php_ver = php_version();
return ($loaderinfo['oscode'] == 'lin' && (($php_ver['major'] == 5 && $php_ver['minor'] >= 3) || $php_ver['major'] > 5) );
}
function ioncube_24_is_enabled()
{
$ic24_enabled = ini_get(IC24_ENABLED_INI_PROPERTY);
return $ic24_enabled;
}
function ioncube_24_information()
{
if (ioncube_24_is_available() && !ioncube_24_is_enabled()) {
$self = get_self();
echo '<div class="ic24">';
echo '<div class="ic24graphic">';
echo '<a target="_blank" href="' . IONCUBE24_URL . '"><img id="ic24logo" src="' . $self . '?page=ic24logo" alt="ionCube24 logo"></a>';
echo '</div>';
echo '<div id="ic24info">';
echo '<p><strong>Bonus Features!</strong> The ionCube Loader can also give ';
echo '<strong>real-time intrusion protection</strong> to protect against malware and <strong>PHP error reporting</strong> ';
echo 'to alert when things go wrong on your website.</p>';
echo '<p>These features are disabled by default but easily activated. ';
echo '<strong><a target="_blank" href="' . IONCUBE24_URL . '">visit ioncube24.com</a></strong> to find out more.</p>';
echo '</div>';
echo '</div>';
}
}
function cli_install_instructions()
{
if (is_php_version_or_greater(5,3)) {
$cli_loader_installed = shell_exec('php -r "echo extension_loaded(\"' . LOADER_EXTENSION_NAME . '\");"');
if (!$cli_loader_installed) {
$cli_php_ini_output = shell_exec("php --ini");
$ini_loader_loc = scan_inis_for_loader();
if (!is_null($cli_php_ini_output)) {
echo '<div class="panel">';
echo '<h4>Loader Installation for Command-Line (CLI) PHP</h4>';
echo "<p>At present it does not look like the ionCube Loader is installed for command-line (CLI) PHP.</p>";
echo "<p>Please note that if you need to run the CLI PHP, such as for <strong>cron jobs</strong>, then please ensure the zend_extension line for the ionCube Loader is included in your CLI PHP configuration.</p>";
if (!empty($ini_loader_loc['location'])) {
echo "<p>The zend_extension line that needs to be copied is:</p>";
echo "<p><kbd>zend_extension = " . $ini_loader_loc['location'] . "</kbd></p>";
}
echo "<p>Your CLI PHP Configuration is:</p>";
echo '<div class="terminal">';
echo "<pre>";
echo $cli_php_ini_output;
echo "</pre>";
echo '</div>';
echo '</div>';
}
}
}
}
function successful_install_end_instructions($rtl_path = null)
{
if (empty($rtl_path)) {
may_need_to_copy_ini();
} elseif (is_string($rtl_path)) {
echo "<p>The runtime loading method of installation was used with path <code>$rtl_path</code></p>";
}
contact_script_provider_instructions();
if (is_legacy_platform()) {
legacy_platform_instructions();
}
if (!is_ms_windows() && is_php_version_or_greater(5,3)) {
cli_install_instructions();
}
uninstall_wizard_instructions();
ioncube_24_information();
}
function loader_major_version_instructions($mv)
{
if ($mv < LATEST_LOADER_MAJOR_VERSION) {
echo "<p><strong>The installed version of the Loader cannot run files produced by the most recent ionCube Encoder.</strong>";
echo " You will need a version " . LATEST_LOADER_MAJOR_VERSION . " ionCube Loader to run such files.</p>";
}
return ($mv < LATEST_LOADER_MAJOR_VERSION);
}
function loader_already_installed($rtl = null)
{
list($lv,$mv,$newer_version) = ioncube_loader_version_information();
$phpv = php_version_maj_min();
$php_str = ' for PHP ' . $phpv;
echo '<div class="success">';
echo '<h4>Loader Installed</h4>';
if ($newer_version) {
echo '<p>The ionCube Loader version ' . $lv . $php_str . ' is <strong>already installed</strong> but it is an old version.';
echo ' It is recommended that the Loader be upgraded to the latest version if possible.</p>';
$know_latest_version = is_string($newer_version);
$is_legacy_loader = loader_major_version_instructions($mv);
echo '</div>';
loader_upgrade_instructions($lv,$newer_version);
} else {
echo '<p>The ionCube Loader version ' . $lv . $php_str . ' is already installed and encoded files should run without problems.</p>';
echo '</div>';
$is_legacy_loader = loader_major_version_instructions($mv,true);
if ($is_legacy_loader) {
loader_upgrade_instructions($lv,true);
}
}
successful_install_end_instructions($rtl);
}
function loader_upgrade_instructions($installed_version,$newer_version)
{
if ($newer_version) {
echo '<div class="panel">';
echo '<h4>Loader Upgrade Instructions</h4>';
$restart_needed = true;
$server_type = find_server_type();
if ($server_type == SERVER_SHARED || $server_type == SERVER_UNKNOWN) {
$loader_path = find_loader(true);
if (!is_string($loader_path) || false === user_ini_space_path($loader_path)) {
$verb_case = ($server_type == SERVER_UNKNOWN)?"may":"will";
echo "<p>Please note that you $verb_case need your system administrator to do the following to upgrade. The web server will need to be restarted after the loader file is changed.</p>";
}
$restart_needed = false;
}
if (is_string($newer_version)) {
$version_str = "version $newer_version";
} else {
$version_str = "a newer version";
}
$loader_name = get_loader_name();
echo "<p>To upgrade from version $installed_version to $version_str of the ionCube Loader, please replace your existing loader file, $loader_name, with
the file of the same name from one of the following packages:</p>";
if (is_ms_windows()) {
$basename = windows_package_name();
} else {
list($basename,$multiple_os_versions) = unix_package_name();
}
echo make_archive_list($basename,array('zip','tar.gz'));
if ($restart_needed) {
echo "<p>Once you have replaced the loader file please restart your web server.</p>";
}
echo '</div>';
}
}
function legacy_platform_warning()
{
$leg_warn = '<p><strong>You are on a platform on which ionCube Loaders are no longer being developed. ';
$leg_warn .= 'Loaders on your platform may not be able to run files produced by the latest ionCube Encoder. ';
$leg_warn .= 'Please switch, if possible, to a platform on which loaders are currently supported. ';
$leg_warn .= 'A list of currently supported platforms is shown on our <a href="' . LOADERS_PAGE . '" target="loaders">loaders page</a>.</strong></p>';
return $leg_warn;
}
function legacy_platform_instructions()
{
echo legacy_platform_warning();
}
function loader_not_installed()
{
$loader = get_loaderinfo();
$sysinfo = get_sysinfo();
$stype = get_request_parameter('stype');
$manual_select = get_request_parameter('manual');
$host_type = find_server_type($stype,$manual_select,true);
if ($host_type != SERVER_UNKNOWN && is_array($loader) && !$sysinfo['DEBUG_BUILD']) {
$warnings = server_restriction_warnings();
if (is_legacy_platform()) {
$warnings[] = legacy_platform_warning();
}
if (empty($_SESSION['use_ini_method']) && $host_type == SERVER_SHARED && runtime_loading_is_possible()) {
$errors = runtime_loading_errors();
} else {
$errors = ini_loader_errors();
$warnings = array_merge($warnings,ini_loader_warnings());
}
if (!empty($errors)) {
if (count($errors) > 1) {
$problem_str = "Please note that the following problems currently exist";
} else {
$problem_str = "Please note that the following problem currently exists";
}
echo '<div class="alert">' .$problem_str . ' with the ionCube Loader installation:';
echo make_list($errors,"ul");
echo '</div>';
}
if (!empty($warnings)) {
$addword = empty($errors)?'':'also';
$plural = (count($warnings)>1)?'s':'';
echo '<div class="warning">';
echo "Please note $addword the following issue$plural:";
echo make_list($warnings,"ul");
echo '</div>';
}
}
if (!isset($stype)) {
echo '<p>To use files that have been protected by the <a href="' . ENCODER_URL . '" target=encoder>ionCube PHP Encoder</a>, a component called the ionCube Loader must be installed.</p>';
}
if (!is_supported_php_version()) {
echo '<p>Your server is running PHP version ' . PHP_VERSION . ' and is
unsupported by ionCube Loaders. Recommended PHP 4 versions are PHP 4.2 or higher,
PHP 5.1 or higher for PHP 5, PHP 7.1 or higher for PHP 7 and PHP 8.1 or higher for PHP 8. Please note that there is not an ionCube Loader for PHP 8.0.</p>';
} elseif ($latest_supported_php_version = is_after_max_php_version_supported()) {
echo '<strong>Your server is running PHP version ' . PHP_VERSION . ' and is
currently unsupported by any ionCube Loaders. <br/>This may change in the future if a Loader is produced for your PHP platform.<br/>In the meantime please downgrade PHP to version ' . $latest_supported_php_version . '.</strong>';
} elseif ($sysinfo['DEBUG_BUILD']) {
echo '<p>Your server is currently running a debug build of PHP. The Loader cannot be installed with a debug build of PHP. Please ensure that PHP is reconfigured with debug disabled. Note that debug builds of PHP cannot help in debugging PHP scripts.</p>';
} elseif (!is_array($loader)) {
if ($loader == ERROR_WINDOWS_64_BIT) {
echo '<p>Loaders for 64-bit PHP on Windows are not currently available. However, if you <b>install and run 32-bit PHP</b> the corresponding 32-bit loader for Windows should work.</p>';
if ($sysinfo['THREAD_SAFE']) {
echo '<li>Download one of the following archives of 32-bit Windows x86 loaders:';
} else {
echo '<li>Download one of the following archives of 32-bit Windows non-TS x86 loaders:';
}
echo make_archive_list(windows_package_name());
} else {
echo '<p>There may not be an ionCube Loader available for your type of system at the moment. However, if you create a <a href="' . SUPPORT_SITE . '">support ticket</a> more advice and information may be available to assist. Please include the URL for this Wizard in your ticket.</p>';
}
} elseif (!$sysinfo['SUPPORTED_COMPILER']) {
$supported_compilers = supported_win_compilers();
$supported_compiler_string = join('/',$supported_compilers);
echo '<p>At the current time the ionCube Loader requires PHP to be built with ' . $supported_compiler_string . '. Your PHP software has been built using ' . $sysinfo['PHP_COMPILER'] . '. Supported builds of PHP are available from <a href="https://windows.php.net/download/">PHP.net</a>.';
} else {
switch ($host_type) {
case SERVER_SHARED:
shared_server();
break;
case SERVER_DEDICATED:
dedicated_server();
break;
case SERVER_LOCAL:
local_install();
break;
default:
echo server_selection_form();
break;
}
}
}
function server_selection_form()
{
$self = get_self();
$timeout = (isset($_SESSION['timing_out']) && $_SESSION['timing_out'])?1:0;
$hostprovider = (!empty($_SESSION['hostprovider']))?$_SESSION['hostprovider']:'';
$hostprovider = htmlspecialchars($hostprovider, ENT_QUOTES, 'UTF-8');
$hosturl = (!empty($_SESSION['hosturl']))?$_SESSION['hosturl']:'';
$hosturl = htmlspecialchars($hosturl, ENT_QUOTES, 'UTF-8');
$form = <<<EOT
<p>This Wizard will give you information on how to install the ionCube Loader.</p>
<p>Please select the type of web server that you have and then click Next.</p>
<script type=text/javascript>
function trim(s) {
return s.replace(/^\s+|\s+$/g,"");
}
function input_ok() {
var l = document.getElementById('local');
if (l.checked) {
return true;
}
var s = document.getElementById('shared');
var d = document.getElementById('dedi');
if (!s.checked && !d.checked) {
alert("Please select one of the server types.");
return false;
} else {
var hn = document.getElementById('hostprovider');
var hu = document.getElementById('hosturl');
var hostprovider = trim(hn.value);
var hosturl = trim(hu.value);
if (!hostprovider || !hosturl) {
alert("Please enter both a hosting provider name and their URL.");
return false;
}
if (hostprovider.length < 1) {
alert("The hosting provider name should be at least 1 character in length.");
return false;
}
if (!hosturl.match(/[A-Za-z0-9-_]+\.[A-Za-z0-9-_%&\?\/.=]+/)) {
alert("The hosting provider URL is invalid.");
return false;
}
if (hosturl.length < 4) {
alert("The hosting provider URL should be at least 4 characters in length.");
return false;
}
}
return true;
}
</script>
<form method=GET action=$self>
<input type="hidden" name="page" value="default">
<input type="hidden" name="timeout" value="$timeout">
<input type=radio id=shared name=stype value=s onclick="document.getElementById('hostinginfo').style.display = 'block';"><label for=shared>Shared <small>(for example, server with FTP access only and no access to php.ini)</small></label><br>
<input type=radio id=dedi name=stype value=d onclick="document.getElementById('hostinginfo').style.display = 'block';"><label for=dedi>Dedicated or VPS <small>(server with full root ssh access)</small></label><br>
<div id="hostinginfo" style="display: none">If you are on a shared or dedicated server, please give your hosting provider and their URL:
<table>
<tr><td><label for=hostprovider>Name of your hosting provider</label></td><td><input type=text id="hostprovider" name=hostprovider value="$hostprovider"></td></tr>
<tr><td><label for=hosturl>URL of your hosting provider</label></td><td><input type=text id="hosturl" name=hosturl value="$hosturl"></td></tr>
</table>
</div>
<input type=radio id=local name=stype value=l onclick="document.getElementById('hostinginfo').style.display = 'none';"><label for=local>Local install</label>
<p><input type=submit value=Next onclick="return (input_ok(this) && showOverlay());"></p>
</form>
EOT;
return $form;
}
function phpinfo_page()
{
info_disabled_check();
if (function_is_disabled('phpinfo')) {
echo "phpinfo is disabled on this server";
} else {
@phpinfo();
}
}
function loader_check_page($ext_name = LOADER_EXTENSION_NAME)
{
heading();
$rtl_path = try_runtime_loading_if_applicable();
if (extension_loaded($ext_name)) {
list($lv,$mv,$newer_version) = ioncube_loader_version_information();
$phpv = php_version_maj_min();
$php_str = ' for PHP ' . $phpv;
echo '<div class="success">';
echo '<h4>Loader Installed Successfully</h4>';
echo '<p>The ionCube Loader version ' . $lv . $php_str . ' <strong>is installed</strong> and encoded files should run successfully.';
if ($newer_version) {
echo ' Please note though that you have an old version of the ionCube Loader.</p>';
$is_legacy_loader = loader_major_version_instructions($mv);
echo '</div>';
loader_upgrade_instructions($lv,$newer_version);
} else {
echo '</p>';
$is_legacy_loader = loader_major_version_instructions($mv);
echo '</div>';
if ($is_legacy_loader) {
loader_upgrade_instructions($lv,true);
}
}
successful_install_end_instructions($rtl_path);
} else {
echo '<div class="failure">';
echo '<h4>Loader Not Installed</h4>';
echo '<p>The ionCube Loader is <b>not</b> currently installed successfully.</p>';
if (!is_null($rtl_path)) {
echo '<p>Runtime loading was attempted but has failed.</p>';
echo '</div>';
$rt_errors = runtime_loading_errors();
if (!empty($rt_errors)) {
list_loader_errors($rt_errors);
}
link_to_php_ini_instructions();
} else {
echo '</div>';
list_loader_errors();
}
}
send_stats('check');
footer(true);
}
function ini_loader_errors()
{
$errors = array();
if (SERVER_SHARED == find_server_type() && !own_php_ini_possible(true)) {
$errors[ERROR_INI_USER_CANNOT_CREATE] = "It appears that you are not be able to create your own ini files on your shared server. <br><strong>You will need to ask your server administrator to install the ionCube Loader for you.</strong>";
}
$loader_loc = find_loader(false);
if (is_string($loader_loc)) {
if (!shared_and_runtime_loading()) {
$sys = get_sysinfo();
if (empty($sys['PHP_INI'])) {
$errors[ERROR_INI_NO_PATH] = 'No file path found for the PHP configuration file (php.ini).';
} elseif (!@file_exists($sys['PHP_INI'])) {
$errors[ERROR_INI_NOT_FOUND] = 'The PHP configuration file (' . $sys['PHP_INI'] .') cannot be found.';
}
}
$errors = $errors + loader_compatibility_test($loader_loc);
} else {
$errors = $errors + $loader_loc;
$fs_location = find_loader_filesystem();
if (!empty($fs_location)) {
$fs_loader_errors = loader_compatibility_test($fs_location);
if (!empty($fs_loader_errors)) {
$errors[ERROR_LOADER_WRONG_GENERAL] = "The loader file found at $fs_location is not the correct one for your system.";
}
$errors = $errors + $fs_loader_errors;
}
}
return $errors;
}
function unix_path_dir($dir = '')
{
if (empty($dir)) {
$dir = dirname(__FILE__);
}
if (is_ms_windows()) {
$dir = str_replace('\\','/',substr($dir,2));
}
return $dir;
}
function unrecognised_inis_webspace($startdir)
{
$ini_list = array();
$ini_name = ini_file_name();
$sys = get_sysinfo();
$depth = substr_count($startdir,'/');
$rel_path = '';
$rootpath = realpath($_SERVER['DOCUMENT_ROOT']);
for ($seps = 0; $seps < $depth; $seps++) {
$full_ini_loc = @realpath($startdir . '/' . $rel_path) . DIRECTORY_SEPARATOR . $ini_name;
if (@file_exists($full_ini_loc) && $sys['PHP_INI'] != $full_ini_loc) {
$ini_list[] = @realpath($full_ini_loc);
}
if (dirname($full_ini_loc) == $rootpath) {
break;
}
$rel_path .= '../';
}
return $ini_list;
}
function correct_loader_wrong_location()
{
$loader_location_pair = array();
$loader_location = find_loader_filesystem();
if (is_string($loader_location) && !empty($loader_location)) {
$loader_errors = loader_compatibility_test($loader_location);
if (empty($loader_errors)) {
$ini_loader = scan_inis_for_loader();
if (!empty($ini_loader['location'])) {
$ini_loader_errors = loader_compatibility_test($ini_loader['location']);
if (!empty($ini_loader_errors)) {
$loader_location_pair['loader'] = $loader_location;
$loader_location_pair['newloc'] = dirname($ini_loader['location']);
}
} else {
$std_dir = loader_install_dir(find_server_type());
$std_ld_path = $std_dir . DIRECTORY_SEPARATOR . get_loader_name();
if (@file_exists($std_ld_path)) {
$stdloc_loader_errors = loader_compatibility_test($std_ld_path);
} else {
$stdloc_loader_errors = array("Loader file does not exist.");
}
if (!empty($stdloc_loader_errors)) {
$loader_location_pair['loader'] = $loader_location;
$loader_location_pair['newloc'] = $std_dir;
}
}
}
}
return $loader_location_pair;
}
function ini_loader_warnings()
{
$warnings = array();
if (find_server_type() == SERVER_SHARED)
{
if (own_php_ini_possible()) {
$sys = get_sysinfo();
$ini_name = ini_file_name();
$rootpath = realpath($_SERVER['DOCUMENT_ROOT']);
$root_ini_file = $rootpath . DIRECTORY_SEPARATOR . $ini_name;
$cgibinpath = @realpath($_SERVER['DOCUMENT_ROOT'] . "/cgi-bin");
$cgibin_ini_file = (empty($cgibinpath))?'':$cgibinpath . DIRECTORY_SEPARATOR . $ini_name;
$here = unix_path_dir();
$ini_files = unrecognised_inis_webspace($here);
$shared_ini_loc = shared_ini_location();
$shared_ini_file = $shared_ini_loc . DIRECTORY_SEPARATOR . $ini_name;
$ini_dir = dirname($sys['PHP_INI']);
$all_ini_locations_used = !empty($ini_files);
foreach ($ini_files as $full_ini_loc) {
$advice = "The file $full_ini_loc is not being recognised by PHP.";
$advice .= " Please check that the name and location of the file are correct.";
if (!ini_same_dir_as_wizard()) {
$ini_loc_dir = dirname($full_ini_loc);
if (!@file_exists($shared_ini_file) && !empty($shared_ini_loc) && $ini_loc_dir != $shared_ini_loc && $ini_dir != $shared_ini_loc) {
$all_ini_locations_used = false;
$advice .= " Please try copying the <code>$full_ini_loc</code> file to <code>" . $shared_ini_loc . "</code>.";
} else {
if (!@file_exists($root_ini_file) && $rootpath != $shared_ini_loc && $full_ini_loc != $rootpath) {
$all_ini_locations_used = false;
$advice .= " Please try copying the <code>$full_ini_loc</code> file to <code>" . $rootpath . "</code>.";
}
if (!empty($cgibin_ini_file) && !@file_exists($cgibin_ini_file) && $cgibinpath != $shared_ini_loc && $full_ini_loc != $cgibinpath && $cgibinpath != $rootpath) {
$all_ini_locations_used = false;
$advice .= " Please try copying the <code>$full_ini_loc</code> file to <code>" . $cgibinpath . "</code>.";
}
$herepath = realpath($here);
$here_ini_file = $herepath . DIRECTORY_SEPARATOR . $ini_name;
if (!@file_exists($here_ini_file) && $herepath != $rootpath && $herepath != $cgibinpath) {
$all_ini_locations_used = false;
$advice .= " It may be necessary to copy the <code>$full_ini_loc</code> file to <code>$herepath</code> and to all " . (is_ms_windows()?'folders':'directories') . ' in which you have encoded files';
}
}
} else {
$all_ini_locations_used = false;
}
$warnings[] = $advice;
}
if ($all_ini_locations_used) {
$warnings[] = "<strong>It looks as if ini files are not being recognised in any of the standard locations in your webspace. Please contact your hosting provider to check whether you can create your own PHP ini file and where it should go.</strong>";
}
} else {
if (own_php_ini_possible(true)) {
$warnings[] = "You may not be able to create your own ini files on your shared server. <br><strong>You might need to ask your server administrator to install the ionCube Loader for you.</strong>";
}
}
} else {
$loader_dir_pair = correct_loader_wrong_location();
if (!empty($loader_dir_pair)) {
$advice = "The correct loader for your system has been found at <code>{$loader_dir_pair['loader']}</code>.";
if ($loader_dir_pair['loader'] != $loader_dir_pair['newloc']) {
$advice .= " Please copy the loader from <code>{$loader_dir_pair['loader']}</code> to <code>{$loader_dir_pair['newloc']}</code>.";
}
$warnings[] = $advice;
}
}
return $warnings;
}
function list_loader_errors($errors = array(),$warnings = array(),$suggest_restart = true)
{
$default = get_default_address();
$retry_message = '';
if (empty($errors)) {
$errors = ini_loader_errors();
if (empty($warnings)) {
$warnings = ini_loader_warnings();
}
}
if (!empty($errors)) {
$try_again = '<a href="#" onClick="window.location.href=window.location.href">try again</a>';
echo '<div class="alert">';
if (count($errors) > 1) {
echo 'The following problems have been found with the ionCube Loader installation:';
$retry_message = "Please correct those errors and $try_again.";
} else {
echo 'The following problem has been found with the ionCube Loader installation:';
$retry_message = "Please correct that error and $try_again.";
}
if (array_key_exists(ERROR_INI_USER_CANNOT_CREATE,$errors)) {
$retry_message = '';
}
echo make_list($errors,"ul");
echo '</div>';
if (!empty($warnings)) {
echo '<div class="warning">';
echo 'Please also note the following:';
echo make_list($warnings,"ul");
echo '</div>';
}
} elseif (!empty($warnings)) {
echo '<div class="warning">';
echo 'There are the following potential problems:';
echo make_list($warnings,"ul");
echo '</div>';
} elseif ($suggest_restart) {
if (SERVER_SHARED == find_server_type()) {
echo "<p>Please contact your server administrator about installing the ionCube Loader.</p>";
} else {
if (selinux_is_enabled()) {
echo "<p>It appears that SELinux is enabled on your server. This might be solved by running the command <code>restorecon [full path to loader file]</code> as root.</p>";
} elseif (grsecurity_is_enabled()) {
echo "<p>It appears that grsecurity is enabled on your server. Please run the command, <code>execstack -c [full path to loader file]</code> and then restart your web server.</p>";
} else {
$sysinfo = get_sysinfo();
$ss = $sysinfo['SS'];
if ($ss == 'PHP-FPM') {
echo "<p>Please check that PHP-FPM has been restarted.</p>";
} elseif (!$sysinfo['CGI_CLI'] || is_ms_windows()) {
echo "<p>Please check that the $ss web server software has been restarted.</p>";
}
}
}
}
echo '<div>';
echo $retry_message;
echo " You may wish to view the following for further help:";
echo make_list(help_resources($errors),"ul");
echo '<a href="' . $default . '">Click here to go back to the start of the Loader Wizard</a>.</div>';
}
function phpconfig_page()
{
info_disabled_check();
$sys = get_sysinfo();
$download = get_request_parameter('download');
$ini_file_name = '';
if (!empty($download)) {
$ini_file_name = get_request_parameter('ininame');
if (empty($ini_file_name)) {
$ini_file_name = ini_file_name();
} else {
if (!preg_match('`^.*\.ini$`',$ini_file_name) || preg_match('`/`',$ini_file_name) || preg_match('`\\\`',$ini_file_name)) {
die("Illegal file name $ini_file_name");
}
}
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename=' . $ini_file_name);
} else {
header('Content-Type: text/plain');
}
$exclude_original = get_request_parameter('newlinesonly');
$prepend = get_request_parameter('prepend');
$stype = get_request_parameter('stype');
$server_type = find_server_type($stype);
if (!empty($exclude_original) || !empty($prepend)) {
$loader_dir = loader_install_dir($server_type);
$zend_lines = zend_extension_lines($loader_dir);
echo join(PHP_EOL,$zend_lines);
echo PHP_EOL;
}
if (empty($ini_file_name) || empty($sys['PHP_INI_DIR']) || ($sys['PHP_INI_BASENAME'] == $ini_file_name)) {
$original_ini_file = isset($sys['PHP_INI'])?$sys['PHP_INI']:'';
} else {
$original_ini_file = $sys['PHP_INI_DIR'] . DIRECTORY_SEPARATOR . $ini_file_name;
}
if (empty($exclude_original) && !empty($original_ini_file) && @file_exists($original_ini_file)) {
if (!empty($download)) {
@readfile($original_ini_file);
} else {
echo all_ini_contents();
}
}
}
function extra_page($check_access_to_info = true)
{
if ($check_access_to_info) {
info_disabled_check();
}
heading();
$sys = get_sysinfo();
$ini_loader = scan_inis_for_loader();
$ini_loader_path = $ini_loader['location'];
$loader_path = find_loader(true);
$ldinf = get_loaderinfo();
$self = get_self();
echo "<h4>Additional Information</h4>";
echo "<table>";
$lines = array();
if (is_string($loader_path)) {
$lines['Loader is at'] = $loader_path;
$loader_system = loader_system($loader_path);
if (!empty($loader_system)) {
$lines['Loader OS code'] = $loader_system['oscode'];
$lines['Loader architecture'] = $loader_system['arch'];
$lines['Loader word size'] = $loader_system['wordsize'];
$lines['Loader PHP version'] = $loader_system['php_version'];
$lines['Loader thread safety'] = $loader_system['thread_safe']?'Yes':'No';
$lines['Loader compiler'] = $loader_system['compiler'];
$lines['Loader version'] = $loader_system['loader_version'];
$lines['File size is'] = filesize($loader_path) . " bytes.";
$lines['MD5 sum is'] = md5_file($loader_path);
}
$lines['Loader file'] = "<a href=\"$self?page=loaderbin\">Download loader file</a>";
} else {
$lines['Loader file'] = "Loader cannot be found.";
}
$lines['Loader found in ini file'] = empty($ini_loader_path)?"No":"Yes";
if (!empty($ini_loader_path) && (!is_string($loader_path) || $ini_loader_path != $loader_path)) {
$lines['Loader location found in ini file'] = $ini_loader_path;
$loader_system = loader_system($ini_loader_path);
if (!empty($loader_system)) {
$lines['Ini Loader OS code'] = $loader_system['oscode'];
$lines['Ini Loader architecture'] = $loader_system['arch'];
$lines['Ini Loader word size'] = $loader_system['wordsize'];
$lines['Ini Loader PHP version'] = $loader_system['php_version'];
$lines['Ini Loader thread safety'] = $loader_system['thread_safe']?'Yes':'No';
$lines['Ini Loader compiler'] = $loader_system['compiler'];
$lines['Ini Loader version'] = $loader_system['loader_version'];
}
}
$lines["OS extra security"] = (selinux_is_enabled() || possibly_selinux())?"SELinux":(grsecurity_is_enabled()?"Grsecurity":"None");
$lines['PHPRC is'] = $sys['PHPRC'];
$lines['INI DIR is'] = $sys['PHP_INI_DIR'];
$lines['Additional INI files'] = $sys['PHP_INI_ADDITIONAL'];
$stype = get_request_parameter('stype');
$server_type = find_server_type($stype);
$lines['Server type is'] = server_type_string();
$lines["PHP uname"] = $ldinf['uname'];
$lines['Server word size is'] = $ldinf['wordsize'];
$lines['Disabled functions'] = ini_get('disable_functions');
$writeable_dirs = writeable_directories();
$lines['Writeable loader locations'] = (empty($writeable_dirs))?"<em>None</em>":join(", ",$writeable_dirs);
if (!empty($_SESSION['hostprovider'])) {
$lines['Hosting provider'] = $_SESSION['hostprovider'];
$lines['Provider URL'] = $_SESSION['hosturl'];
}
foreach ($lines as $h => $i) {
$v = (empty($i))?'<em>EMPTY</em>':$i;
echo '<tr><th>'. $h . ':</th>' . '<td>' . $v . '</td></tr>';
}
echo "</table>";
footer(true);
}
function loaderbin_page()
{
info_disabled_check();
$loader_path = find_loader(true);
if (is_string($loader_path)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='. basename($loader_path));
@readfile($loader_path);
}
}
function GoDaddy_root($html_root = '')
{
if (empty($_SESSION['not_go_daddy']) && empty($_SESSION['godaddy_root'])) {
$godaddy_pattern = "[\\/]home[\\/]content[\\/][0-9a-z][\\/][0-9a-z][\\/][0-9a-z][\\/][0-9a-z]+[\\/]html";
if (empty($html_root)) {
$html_root = $_SERVER['DOCUMENT_ROOT'];
}
if (preg_match("@$godaddy_pattern@i",$html_root,$matches)) {
$_SESSION['godaddy_root'] = $matches[0];
} else {
$_SESSION['not_go_daddy'] = 1;
$_SESSION['godaddy_root'] = '';
}
} elseif (!empty($_SESSION['not_go_daddy'])) {
$_SESSION['godaddy_root'] = '';
}
if (!empty($_SESSION['godaddy_root'])) {
$_SESSION['hostprovider'] = 'GoDaddy';
$_SESSION['hosturl'] = 'www.godaddy.com';
}
return $_SESSION['godaddy_root'];
}
function GoDaddy_windows_instructions()
{
$instr = "It appears that you are hosted on a Windows server at GoDaddy.<br/>";
$instr .= "Please change to a Linux hosting plan at GoDaddy.<br />";
$instr .= "If you <a href=\"https://help.godaddy.com/\">contact their support team</a> they should be able to switch you to a Linux server.";
echo $instr;
}
function GoDaddy_linux_instructions($html_dir)
{
$base = get_base_address();
$loader_name = get_loader_name();
$zend_extension_line="<code>zend_extension = $html_dir/ioncube/$loader_name</code>";
$php_ini_name = is_php_version_or_greater(5,0)?'php5.ini':'php.ini';
$ini_path = $html_dir . '/' . $php_ini_name;
$instr = array();
$instr[] = 'In your html directory, ' . $html_dir . ', create a sub-directory called <b>ioncube</b>.';
if (@file_exists($ini_path)) {
$instr[] = "Edit the $php_ini_name in your $html_dir and add the following line to the <b>top</b> of the file:<br>" . $zend_extension_line ;
} else {
$instr[] = "<a href=\"$base&page=phpconfig&ininame=$php_ini_name&stype=s&download=1&prepend=1\">Save this $php_ini_name file</a> and upload it to your html directory, $html_dir";
}
$instr[] = 'Download the <a target="_blank" href="' . IONCUBE_DOWNLOADS_SERVER . '"/ioncube_loaders_lin_x86.zip">Linux ionCube Loaders</a>.';
$instr[] = 'Unzip the loaders and upload them into the ioncube directory you created previously.';
$instr[] = 'The encoded files should now be working.';
echo '<div class=panel>';
echo (make_list($instr));
echo '</div>';
}
function GoDaddy_page()
{
$base = get_base_address();
heading();
$inst_str = '<h4>GoDaddy Installation Instructions</h4>';
$inst_str .= '<p>It appears that you are hosted with GoDaddy (<a target="_blank" href="https://www.godaddy.com/">www.godaddy.com</a>). ';
$inst_str .= "If that is <b>not</b> the case then please <a href=\"$base&page=default&host=ngd\">click here to go to the main page of this installation wizard</a>.</p>";
$inst_str .= "<p>If you have already installed the loader then please <a href=\"$base&page=loader_check\" onclick=\"showOverlay();\">click here to test the loader</a>.</p>";
echo $inst_str;
if (is_ms_windows()) {
GoDaddy_windows_instructions();
} else {
GoDaddy_linux_instructions($_SESSION['godaddy_root']);
}
send_stats('gd_default');
footer(true);
}
function get_request_parameter($param_name)
{
static $request_array;
if (!isset($request_array)) {
if (isset($_GET)) {
$request_array = $_GET;
} elseif (isset($HTTP_GET_VARS)) {
$request_array = $HTTP_GET_VARS;
}
}
if (isset($request_array[$param_name])) {
$return_value = strip_tags($request_array[$param_name]);
} else {
$return_value = null;
}
return $return_value;
}
function make_list($list_items,$list_type='ol')
{
$html = '';
if (!empty($list_items)) {
$html .= "<$list_type>";
$html .= '<li>';
$html .= join('</li><li>',$list_items);
$html .= '</li>';
$html .= "</$list_type>";
}
return $html;
}
function make_archive_list($basename,$archives_list = array(),$download_server = IONCUBE_DOWNLOADS_SERVER)
{
if (empty($archives_list)) {
$archives_list = array('tar.gz','zip');
}
foreach ($archives_list as $a) {
$link_text = $a;
$ext_sep = '.';
$archive_list[] = "<a href=\"$download_server/$basename$ext_sep$a\">$link_text</a>";
}
return make_list($archive_list,"ul");
}
function error($m)
{
die("<b>ERROR:</b> <span class=\"error\">$m</span><p>Please help us improve this script by <a href=\"". SUPPORT_SITE . "\">reporting this error</a> and including the URL to the script so that we can test it.");
}
function filter_server_input($server_var)
{
$res = htmlspecialchars($_SERVER[$server_var], ENT_QUOTES, "UTF-8");
return $res;
}
function failsafe_get_self()
{
$result = '';
$sfn = filter_server_input('SCRIPT_FILENAME');
$dr = $_SERVER['DOCUMENT_ROOT'];
if (!empty($sfn) && !empty($dr)) {
if ($dr == '/' || $dr == '\\') {
$result = $sfn;
} else {
$drpos = strpos($sfn,$dr);
if ($drpos === 0) {
$drlen = strlen($dr);
$result = substr($sfn,$drlen);
}
}
$result = str_replace('\\','/',$result);
}
if (empty($result)) {
$result = DEFAULT_SELF;
}
return $result;
}
function get_self()
{
$page = '';
if (empty($_SERVER['PHP_SELF'])) {
if (empty($_SERVER['SCRIPT_NAME'])) {
if (empty($_SERVER['REQUEST_URI'])) {
$page = failsafe_get_self();
} else {
$page = filter_server_input('REQUEST_URI');
}
} else {
$page = filter_server_input('SCRIPT_NAME');
}
} else {
$page = filter_server_input('PHP_SELF');
}
return $page;
}
function get_default_page()
{
$godaddy_root = GoDaddy_root();
if (empty($godaddy_root)) {
$page = 'default';
} else {
$page = 'GoDaddy';
}
return $page;
}
function get_base_address()
{
$self = get_self();
$remote_timeout = (isset($_SESSION['timing_out']) && $_SESSION['timing_out'])?'timeout=1':'timeout=0';
$using_ini = (isset($_SESSION['use_ini_method']) && $_SESSION['use_ini_method'])?'ini=1':'ini=0';
return $self . '?' . $remote_timeout . '&' . $using_ini;
}
function get_default_address($include_timeout = true)
{
if ($include_timeout) {
$base = get_base_address();
$base .= "&";
} else {
$base = get_self();
$base .= "?";
}
$page = get_default_page();
return $base . 'page=' . $page;
}
function heading()
{
$self = get_self();
echo <<<EOT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN "http://www.w3.org/TR/html4/loose.dtd">
<html>
<meta name="robots" content="noindex, nofollow">
<head>
<title>ionCube Loader Wizard</title>
<link rel="stylesheet" type="text/css" href="$self?page=css">
<script type="text/javascript">
function showOverlay()
{
document.getElementById('overlay').style.display = 'block';
return true;
}
function hideOverlay()
{
document.getElementById('overlay').style.display = 'none';
return true;
}
</script>
</head>
<body onload="hideOverlay()">
<div id="overlay">
<div id="inner_overlay">Checking server configuration<br>Please wait</div>
</div>
<div id="header">
<img src="?page=logo" alt="ionCube logo">
</div>
<div id="important">
<h3 class="important">IMPORTANT: Ensure that This Script Is Removed When No Longer Required</h3>
</div>
<div id="main">
<h2>ionCube Loader Wizard</h2>
EOT;
}
function footer($update_info = null)
{
$self = get_self();
$base = get_base_address();
$default = get_default_address(false);
$year = gmdate("Y");
echo "</div>";
echo "<div id=\"footer\">" .
"Copyright ionCube Ltd. 2002-$year | " .
"Loader Wizard version " . script_version() . " ";
if ($update_info === true) {
$update_info = check_for_wizard_update(false);
}
$loader_wizard_loc = LOADER_WIZARD_URL;
$wizard_version_string =<<<EOT
<script type="text/javascript">
var xmlhttp;
function version_check()
{
var body = document.getElementsByTagName('body')[0];
var ldel = document.getElementById('loading');
if (!ldel) {
body.innerHTML += '<div id="loading"></div>';
ldel = document.getElementById('loading');
}
ldel.innerHTML = '<p>Retrieving Wizard version information<br>Please wait</p>';
ldel.style.display = 'block';
ldel.style.height = '300px';
ldel.style.left = '200px';
ldel.style.border = '4px #660000 solid';
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
} else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
var loadedOkay = 0;
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
var wizardversion = xmlhttp.responseText;
var msg;
clearTimeout(xmlHttpTimeout);
buttons = '';
if (wizardversion == '1') {
msg = 'You have the current version of the<br>ionCube Loader Wizard';
} else if (wizardversion != '0') {
msg = 'A new version, ' + wizardversion + ', of the loader wizard is available';
buttons = '<button onclick="document.getElementById(\'loading\').style.display=\'none\'; window.open(\'$loader_wizard_loc\'); return false">Get new version</button> ';
} else {
msg = 'Wizard version information cannot be obtained from the<br>ionCube server';
}
buttons += '<button onclick="document.getElementById(\'loading\').style.display=\'none\'; return false">Close this box</button>';
ldel.innerHTML = '<p>' + msg + '<br>' + buttons + '</p>';
}
}
xmlhttp.open("GET",'$self?page=wizardversion&wizard_only=1&clear_info=1',true);
xmlhttp.send();
var xmlHttpTimeout=setTimeout(ajaxTimeout,7000);
}
function ajaxTimeout(){
xmlhttp.abort();
msg = 'Wizard version information cannot be obtained from the<br>ionCube server';
button = '<button onclick="document.getElementById(\'loading\').style.display=\'none\'; return false">Close this box</button>';
var ldel = document.getElementById('loading');
ldel.innerHTML = '<p>' + msg + '<br>' + button + '</p>';
}
</script>
EOT;
$wizard_version_string .= '(';
if ($update_info === null) {
$wizard_version_string .= '<a target="_blank" href="' . $loader_wizard_loc . '" onclick="version_check();return false;">check for new version</a>';
} else if ($update_info !== false) {
$wizard_version_string .= '<a href="' . LOADERS_PAGE .'" target="_blank">download version ' . $update_info . '</a>';
} else {
$wizard_version_string .= "current";
}
$wizard_version_string .= ')';
echo $wizard_version_string;
$server_type_code = server_type_code();
if (!info_should_be_disabled(true)) {
echo " | <a href=\"$base&page=phpinfo\" target=\"phpinfo\">phpinfo</a>";
echo " | <a href=\"$base&page=phpconfig\" target=\"phpconfig\">config</a>";
echo " | <a href=\"$base&page=extra&stype=$server_type_code\" target=\"extra\">additional</a>";
}
echo " | <a href=\"$default\" onclick=\"showOverlay();\">wizard start</a>";
echo " | <a href=\"$base&page=loader_check\" onclick=\"showOverlay();\">loader test</a>";
echo ' | <a href="' . LOADERS_PAGE . '" target="loaders">loaders</a>';
echo "</div>\n";
echo "\n</body></html>\n";
}
function css_page()
{
header('Content-Type: text/css');
echo <<<EOT
body {
font-family: verdana, helvetica, arial, sans-serif;
font-size: 10pt;
line-height: 150%;
margin: 0px;
min-height: 400px;
position: relative;
}
code {
color: #c00080;
}
li {
margin-top: 10px;
}
#overlay {
display: block;
z-index: 100;
position: absolute;
top: 0;
left: 0;
padding: 0;
margin: 0;
width: 100%;
height: 100%;
background-color: white;
}
#inner_overlay {
display: block;
z-index: 100;
position: absolute;
font-size: 200%;
color: #660000;
top: 50%;
left: 25%;
width: 460px;
height: 460px;
line-height: 200%;
text-align: center;
vertical-align: middle;
}
#loading {
display: block;
position: absolute;
top: 33%;
left: 25%;
margin: auto;
height: 320px;
width: 460px;
padding: 4px;
color: #660000;
background-color: white;
z-index: 100;
}
#loading p {
position: absolute;
margin-top: 10px;
text-align: center;
vertical-align: middle;
padding-left: 40px;
padding-right: 30px;
font-size: 200%;
line-height: 200%;
}
#loading p span#status{
font-size: 60%;
line-height: 120%;
}
#loading p#noscript {
font-size: 120%;
line-height: 120%;
position: absolute;
text-align: left;
padding-top: 10px;
bottom: 0;
}
#loading p#noscript a {
text-align: center;
}
#loading button {
margin-top: 20px;
line-height: 100%;
padding-top: 4px;
padding-bottom: 4px;
}
h4 {
margin-bottom: 0;
padding-bottom: 4px;
}
p,#main div {
max-width: 1000px;
width: 75%;
}
#hostinginfo {
margin-top: 10px;
margin-left: 20px;
}
#hostinginfo table {
font-size: 1.00em;
}
#hostinginfo table td {
padding-right: 4px;
}
#hostinginfo input {
margin-top: 6px;
}
#hostinginfo label {
margin-left: 6px;
}
th {
text-align: left;
}
#important {
margin-top: 12px;
}
h3.important {
margin: 0;
border: 0;
border-top: 1px solid #660000;
border-bottom: 1px solid #660000;
padding: 1ex 0 1ex 0;
background-color: #CB2430;
text-align: center;
color: #ffffff;
width: 100%;
}
.alert {
margin: 2ex 0;
border: 1px solid #660000;
padding: 1ex 1em;
background-color: #ffeeee;
color: #660000;
width: 75%;
}
.warning {
margin: 2ex 0;
border: 1px solid #FFBF00;
padding: 1ex 1em;
background-color: #FDF5E6;
color: #000000;
width: 75%;
}
.success {
margin: 2ex 0;
border: 1px solid #006600;
padding: 1ex 1em;
background-color: #EEFFEE;
color: #000000;
width: 75%;
}
.error {
color: #FF0000;
}
.panel {
border: 1px solid #c0c0c0;
background-color: #f0f0f0;
width: 75%;
padding: 1ex 1em;
}
.terminal {
border: none;
background-color: #000000;
color: #ffffff;
width: 50%;
padding: 1ex 1em;
}
#header {
background: #fff;
}
#footer {
border-top: 1px solid #404040;
margin-top: 20px;
padding-top: 10px;
padding-left: 20px;
font-size: 75%;
text-align: left;
}
#main {
margin: 20px;
}
#main .ic24 {
position: relative;
width: 75%;
height: auto;
border-width: 1px 1px 1px 1px;
border-style: solid;
border-color: #4B8DF8;
background-color: #EFEFFF;
padding: 12px;
padding-top: 16px;
padding-bottom: 8px;
margin-top: 20px;
overflow: hidden;
}
#main .ic24 p {
width: 100%;
}
#main .ic24graphic {
position: relative;
width: auto;
height: auto;
border: none;
padding: 0px;
padding-right: 16px;
margin: 0px;
float: left;
}
#main #ic24info {
position: relative;
width: auto;
height: auto;
float: left;
}
#main #ic24info a {
color: #0B4DB8;
text-decoration: none;
}
#main #ic24logo {
max-width: 132px;
max-height: 132px;
}
EOT;
}
function logo_page()
{
$img_encoded = 'iVBORw0KGgoAAAANSUhEUgAAAakAAACABAMAAABD1osiAAAAKlBMVEUAAAAAAADnHCwAAAAAAAAAAAAAAAAAAABMCQ4AAADnHCznHCznHCwAAAAjcBE1AAAADHRSTlMAeDRHwSqg4BJl/PLTJLuIAAAF1UlEQVR42u2by4vTQBzHp3TTzR6EBtfXYS/+BZW6Pg6FFavgoRDBBx4KFd+HQgWFvQQqiuJhoeL7sP+LR0EPlj6yPfz+F5NMZ77TmmJjM3ZT5nNpOzvNzGcev5lMusxgMBgMBoPBYDAYDAaDwWDQwel5YRnC/jkvbZYdjFV2MFbZwVhlB2OVIVZyb2HIED/n5AfLEj/nhWUJY5UdjFV2MFbZwVgdMqzNZydXz2qrf59Kq2a1NmTsRnfVrLZOfj3VrrkrZuVb/dpBvZEJqzOOc5TNQ75rjXKDtV+ZsNoi6rJ52OhZwxONwiGwsi46zqnt1Kx8r7N8q/wmRfhP3BSsrK7VW/u13krDysGwT8o5kvilxa2YZ/U2eulEC0KhCTlLCo0UrPYff7Tfe+2lWt0glTT6qjB02e0eW6ZVjiZYaF4hq+eXlmll1yik75TL5eMeDVOxsj89hNQyrN5QyDFRm9GCVmCZVrYXBr4OE9w8ZFbBCNr+x646ycAhs/o3moFUj62Y1UY4/txVs9oLrAZs1azCAVhaNSsLgXNpVt/+dlNXZAplx4mLiXecU5hHhcBqN6lV/p3znk1xEYUltfr+t0J/4dN1jwKGWIg+VKuBdL5JAQ9EYj34ILOAjWq12lG+eE2xsk9EF/7CFN7WKOCpq9kK2/CTyp93mFUbpyKRZmwNi2oX4Y0dfgULd8QL4vRdvVavJ+6XYLVPIQjmHq9xAqvbJBTa8paTBCOtVpZHY1DrSmCF7flABotBIiuLJM+RQdJJO1qoVnUKqfLh1pBWrX10YVu0ciuRVXjlfpUiXGSmp85xdFaaT7thZUV95I5DRldaDYJPT8oXmyQqnYP0nFZetL23tgjtsT/e8uc9mKa3XsFqL3Rpy3YsCSufhwmrJgbeGmo/jxUCjd2UzWWFg1EuEzv6rJoY4ftyQapghBRElda5cxKrEfaPvGPWw+Esyx1ps8pHhaP0LqxK8p7KZwFHklt1kEqNcbsNcFfT12a1zgtEv7WFVZehB93xUGVJrPg7MXgPxotDUWlCV5dVhYtgjhV5KuLd+jixktjqYHoHmVcLw9fSt2ry8lDBlrAqKomN5FZI5aX0+Rztqmk7uqywtGKhRQ+KmbeT3AoDDN89gsJQBQ1WWFrFpmgkIruq2kpuhWCASFNBYXxN1GGFKk1XqqLWiXjeOvpv3n2gpBDm4dtL1aqnyaqAcA2bGCu0d3Ir5GkSPasKsFlO3WpNGf68P3wdVhs84tRIRZ/VEUwWfIyxwo4puRUiDh0+q2jntnJWOf6aplVv+VZ5VGMBq3tlhQuarNYnw3V9Zgzkr8PFYiByAi0xcM7ILva+7kJWNeyktVoV5l2FeSI1kluh8UKrlnar6dv2qNhejBVG6yDeaifOajg5X9tR4sH/sLIIBeFTjJV4JMImmd5KNmGFvHxfyV9Guq2mDvnQc9NWyIuOBWrD2BSzZ4fsHi6rzUq26cRdY2e2VSU+ChJ6IDdh1Zi+wylAVa9VfWqu+2y2VYFiO6uGzHsTVj01WOxgsOq3KqB0nMbMsLK96fNxKVASgrDCSogcHjpbq5WNg1WcVsRY4Zi3i1Xblqm7OLFXrHbRWn2GxUG/FduX0yIHwRlWFomD3ojrT+Vxje+KE3tYiQ6ym3JJKKidnW9rscJkuSwOiUdsphXO5P2724y9PPOI+njMMSyxOzWiTViF7/0v4kS6gzEcZA0545X0WbFmVClnk1B4vJXsDYArcPzXitUxCnhW5f070SyXHGfTw1jUYVUgMGKzrTBKQQk/LonYzSlWxToyFuOapaXRim2hqd2/WbFbJEBlLTx8k1a1QNmaai0eUMBAp5XVFFIdNtMqVqs/nhmvpGQuSJRWUmHoMsl5klzRacWsE4Sn3TOswMtH9Mfvbj+L36JNWrFzUgqcE6ofdf8X9PXN6qWjbF5eOverV51ye/ICd+NCWv549er0ha3o69vMYDAYDAaDwWAwGAwGg8FgSJffF2mwYDNbStYAAAAASUVORK5CYII=';
header('Content-Type: image/png');
header('Cache-Control: public');
echo base64_decode($img_encoded);
}
function ic24logo_page()
{
$img_encoded = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6b3NiPSJodHRwOi8vd3d3Lm9wZW5zd2F0Y2hib29rLm9yZy91cmkvMjAwOS9vc2IiCiAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIKICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIgogICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB2ZXJzaW9uPSIxLjAiCiAgIHdpZHRoPSI2OTAiCiAgIGhlaWdodD0iNjkxLjI1IgogICB2aWV3Qm94PSIwIDAgNTUyIDU1MyIKICAgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQgbWVldCIKICAgaWQ9InN2ZzMwMzUiCiAgIGlua3NjYXBlOnZlcnNpb249IjAuNDguNSByMTAwNDAiCiAgIHNvZGlwb2RpOmRvY25hbWU9ImlvbkN1YmUyNF9jdWJlLnN2ZyI+CiAgPGRlZnMKICAgICBpZD0iZGVmczMwODMiPgogICAgPGxpbmVhckdyYWRpZW50CiAgICAgICBpZD0ibGluZWFyR3JhZGllbnQ1MzQ5IgogICAgICAgb3NiOnBhaW50PSJzb2xpZCI+CiAgICAgIDxzdG9wCiAgICAgICAgIHN0eWxlPSJzdG9wLWNvbG9yOiMxMjczYjg7c3RvcC1vcGFjaXR5OjE7IgogICAgICAgICBvZmZzZXQ9IjAiCiAgICAgICAgIGlkPSJzdG9wNTM1MSIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8bGluZWFyR3JhZGllbnQKICAgICAgIGlkPSJsaW5lYXJHcmFkaWVudDUzNDMiCiAgICAgICBvc2I6cGFpbnQ9InNvbGlkIj4KICAgICAgPHN0b3AKICAgICAgICAgc3R5bGU9InN0b3AtY29sb3I6IzAwMDAwMDtzdG9wLW9wYWNpdHk6MTsiCiAgICAgICAgIG9mZnNldD0iMCIKICAgICAgICAgaWQ9InN0b3A1MzQ1IiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxsaW5lYXJHcmFkaWVudAogICAgICAgaWQ9ImxpbmVhckdyYWRpZW50NTMzNyIKICAgICAgIG9zYjpwYWludD0ic29saWQiPgogICAgICA8c3RvcAogICAgICAgICBzdHlsZT0ic3RvcC1jb2xvcjojMTI3M2I4O3N0b3Atb3BhY2l0eToxOyIKICAgICAgICAgb2Zmc2V0PSIwIgogICAgICAgICBpZD0ic3RvcDUzMzkiIC8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPGxpbmVhckdyYWRpZW50CiAgICAgICBpZD0ibGluZWFyR3JhZGllbnQ1MzMxIgogICAgICAgb3NiOnBhaW50PSJzb2xpZCI+CiAgICAgIDxzdG9wCiAgICAgICAgIHN0eWxlPSJzdG9wLWNvbG9yOiMwMDAwMDA7c3RvcC1vcGFjaXR5OjE7IgogICAgICAgICBvZmZzZXQ9IjAiCiAgICAgICAgIGlkPSJzdG9wNTMzMyIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8bGluZWFyR3JhZGllbnQKICAgICAgIGlkPSJsaW5lYXJHcmFkaWVudDUzMjUiCiAgICAgICBvc2I6cGFpbnQ9InNvbGlkIj4KICAgICAgPHN0b3AKICAgICAgICAgc3R5bGU9InN0b3AtY29sb3I6IzEyNzNiODtzdG9wLW9wYWNpdHk6MDsiCiAgICAgICAgIG9mZnNldD0iMCIKICAgICAgICAgaWQ9InN0b3A1MzI3IiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxsaW5lYXJHcmFkaWVudAogICAgICAgaWQ9ImxpbmVhckdyYWRpZW50Mzg4NSIKICAgICAgIG9zYjpwYWludD0ic29saWQiPgogICAgICA8c3RvcAogICAgICAgICBzdHlsZT0ic3RvcC1jb2xvcjojMTI3M2I4O3N0b3Atb3BhY2l0eToxOyIKICAgICAgICAgb2Zmc2V0PSIwIgogICAgICAgICBpZD0ic3RvcDM4ODciIC8+CiAgICA8L2xpbmVhckdyYWRpZW50PgogICAgPGxpbmVhckdyYWRpZW50CiAgICAgICBpZD0ibGluZWFyR3JhZGllbnQzODc5IgogICAgICAgb3NiOnBhaW50PSJzb2xpZCI+CiAgICAgIDxzdG9wCiAgICAgICAgIHN0eWxlPSJzdG9wLWNvbG9yOiMxMjczYjg7c3RvcC1vcGFjaXR5OjE7IgogICAgICAgICBvZmZzZXQ9IjAiCiAgICAgICAgIGlkPSJzdG9wMzg4MSIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8bGluZWFyR3JhZGllbnQKICAgICAgIGlkPSJsaW5lYXJHcmFkaWVudDM4NzMiCiAgICAgICBvc2I6cGFpbnQ9InNvbGlkIj4KICAgICAgPHN0b3AKICAgICAgICAgc3R5bGU9InN0b3AtY29sb3I6IzEyNzNiODtzdG9wLW9wYWNpdHk6MTsiCiAgICAgICAgIG9mZnNldD0iMCIKICAgICAgICAgaWQ9InN0b3AzODc1IiAvPgogICAgPC9saW5lYXJHcmFkaWVudD4KICAgIDxsaW5lYXJHcmFkaWVudAogICAgICAgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIgogICAgICAgeGxpbms6aHJlZj0iI2xpbmVhckdyYWRpZW50NTMzNyIKICAgICAgIGlkPSJsaW5lYXJHcmFkaWVudDUzNDEiCiAgICAgICB4MT0iNDQzNS40NDI0IgogICAgICAgeTE9IjI5NDkuMDQyIgogICAgICAgeDI9IjQ4MzQuMzkyMSIKICAgICAgIHkyPSIyOTQ5LjA0MiIKICAgICAgIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiAvPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDMxNDIiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDE2MDM0LDIyMzYgYyAtMywtOCAtMywtMzQwIC0xLC03MzggNSwtNzg5IDQsLTc4NiA2NiwtOTc3IDQyLC0xMzAgOTIsLTIxNCAxODUsLTMwNyAxMjgsLTEyOCAyNTcsLTE4MSA0NjcsLTE5MSAyNDYsLTEyIDQ2Miw2OSA2MjksMjM3IDM2LDM2IDgwLDg3IDk4LDExNCAxNywyNyAzMyw0OCAzMyw0NSAxLC0yIDcsLTgwIDEzLC0xNzQgbCAxMSwtMTcwIDE3OSwtMyAxNzgsLTIgLTYsNDIgYyAtNCwyNCAtOSw1MTQgLTEyLDEwOTEgbCAtNiwxMDQ3IC0xOTYsLTIgLTE5NywtMyAtNSwtNzMwIGMgLTQsLTUwOCAtOSwtNzQwIC0xNywtNzYyIC0xMDIsLTI4NCAtMzY2LC00NDUgLTY0NCwtMzkzIC0xNzgsMzQgLTI5OSwxNzIgLTM1MSw0MDAgLTIxLDkxIC0yMiwxMjMgLTI1LDc5MyBsIC00LDY5NyAtMTk1LDAgYyAtMTU4LDAgLTE5NiwtMyAtMjAwLC0xNCB6IgogICAgICAgICBpZD0icGF0aDMxNDQiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2NsaXBQYXRoPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDMxNDYiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDE2MDM0LDIyMzYgYyAtMywtOCAtMywtMzQwIC0xLC03MzggNSwtNzg5IDQsLTc4NiA2NiwtOTc3IDQyLC0xMzAgOTIsLTIxNCAxODUsLTMwNyAxMjgsLTEyOCAyNTcsLTE4MSA0NjcsLTE5MSAyNDYsLTEyIDQ2Miw2OSA2MjksMjM3IDM2LDM2IDgwLDg3IDk4LDExNCAxNywyNyAzMyw0OCAzMyw0NSAxLC0yIDcsLTgwIDEzLC0xNzQgbCAxMSwtMTcwIDE3OSwtMyAxNzgsLTIgLTYsNDIgYyAtNCwyNCAtOSw1MTQgLTEyLDEwOTEgbCAtNiwxMDQ3IC0xOTYsLTIgLTE5NywtMyAtNSwtNzMwIGMgLTQsLTUwOCAtOSwtNzQwIC0xNywtNzYyIC0xMDIsLTI4NCAtMzY2LC00NDUgLTY0NCwtMzkzIC0xNzgsMzQgLTI5OSwxNzIgLTM1MSw0MDAgLTIxLDkxIC0yMiwxMjMgLTI1LDc5MyBsIC00LDY5NyAtMTk1LDAgYyAtMTU4LDAgLTE5NiwtMyAtMjAwLC0xNCB6IgogICAgICAgICBpZD0icGF0aDMxNDgiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2NsaXBQYXRoPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDMxNTAiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDE2MDM0LDIyMzYgYyAtMywtOCAtMywtMzQwIC0xLC03MzggNSwtNzg5IDQsLTc4NiA2NiwtOTc3IDQyLC0xMzAgOTIsLTIxNCAxODUsLTMwNyAxMjgsLTEyOCAyNTcsLTE4MSA0NjcsLTE5MSAyNDYsLTEyIDQ2Miw2OSA2MjksMjM3IDM2LDM2IDgwLDg3IDk4LDExNCAxNywyNyAzMyw0OCAzMyw0NSAxLC0yIDcsLTgwIDEzLC0xNzQgbCAxMSwtMTcwIDE3OSwtMyAxNzgsLTIgLTYsNDIgYyAtNCwyNCAtOSw1MTQgLTEyLDEwOTEgbCAtNiwxMDQ3IC0xOTYsLTIgLTE5NywtMyAtNSwtNzMwIGMgLTQsLTUwOCAtOSwtNzQwIC0xNywtNzYyIC0xMDIsLTI4NCAtMzY2LC00NDUgLTY0NCwtMzkzIC0xNzgsMzQgLTI5OSwxNzIgLTM1MSw0MDAgLTIxLDkxIC0yMiwxMjMgLTI1LDc5MyBsIC00LDY5NyAtMTk1LDAgYyAtMTU4LDAgLTE5NiwtMyAtMjAwLC0xNCB6IgogICAgICAgICBpZD0icGF0aDMxNTIiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2NsaXBQYXRoPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDMxNTQiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDE2MDM0LDIyMzYgYyAtMywtOCAtMywtMzQwIC0xLC03MzggNSwtNzg5IDQsLTc4NiA2NiwtOTc3IDQyLC0xMzAgOTIsLTIxNCAxODUsLTMwNyAxMjgsLTEyOCAyNTcsLTE4MSA0NjcsLTE5MSAyNDYsLTEyIDQ2Miw2OSA2MjksMjM3IDM2LDM2IDgwLDg3IDk4LDExNCAxNywyNyAzMyw0OCAzMyw0NSAxLC0yIDcsLTgwIDEzLC0xNzQgbCAxMSwtMTcwIDE3OSwtMyAxNzgsLTIgLTYsNDIgYyAtNCwyNCAtOSw1MTQgLTEyLDEwOTEgbCAtNiwxMDQ3IC0xOTYsLTIgLTE5NywtMyAtNSwtNzMwIGMgLTQsLTUwOCAtOSwtNzQwIC0xNywtNzYyIC0xMDIsLTI4NCAtMzY2LC00NDUgLTY0NCwtMzkzIC0xNzgsMzQgLTI5OSwxNzIgLTM1MSw0MDAgLTIxLDkxIC0yMiwxMjMgLTI1LDc5MyBsIC00LDY5NyAtMTk1LDAgYyAtMTU4LDAgLTE5NiwtMyAtMjAwLC0xNCB6IgogICAgICAgICBpZD0icGF0aDMxNTYiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2NsaXBQYXRoPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDMxNTgiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDE2MDM0LDIyMzYgYyAtMywtOCAtMywtMzQwIC0xLC03MzggNSwtNzg5IDQsLTc4NiA2NiwtOTc3IDQyLC0xMzAgOTIsLTIxNCAxODUsLTMwNyAxMjgsLTEyOCAyNTcsLTE4MSA0NjcsLTE5MSAyNDYsLTEyIDQ2Miw2OSA2MjksMjM3IDM2LDM2IDgwLDg3IDk4LDExNCAxNywyNyAzMyw0OCAzMyw0NSAxLC0yIDcsLTgwIDEzLC0xNzQgbCAxMSwtMTcwIDE3OSwtMyAxNzgsLTIgLTYsNDIgYyAtNCwyNCAtOSw1MTQgLTEyLDEwOTEgbCAtNiwxMDQ3IC0xOTYsLTIgLTE5NywtMyAtNSwtNzMwIGMgLTQsLTUwOCAtOSwtNzQwIC0xNywtNzYyIC0xMDIsLTI4NCAtMzY2LC00NDUgLTY0NCwtMzkzIC0xNzgsMzQgLTI5OSwxNzIgLTM1MSw0MDAgLTIxLDkxIC0yMiwxMjMgLTI1LDc5MyBsIC00LDY5NyAtMTk1LDAgYyAtMTU4LDAgLTE5NiwtMyAtMjAwLC0xNCB6IgogICAgICAgICBpZD0icGF0aDMxNjAiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2NsaXBQYXRoPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDMxNjIiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDE2MDM0LDIyMzYgYyAtMywtOCAtMywtMzQwIC0xLC03MzggNSwtNzg5IDQsLTc4NiA2NiwtOTc3IDQyLC0xMzAgOTIsLTIxNCAxODUsLTMwNyAxMjgsLTEyOCAyNTcsLTE4MSA0NjcsLTE5MSAyNDYsLTEyIDQ2Miw2OSA2MjksMjM3IDM2LDM2IDgwLDg3IDk4LDExNCAxNywyNyAzMyw0OCAzMyw0NSAxLC0yIDcsLTgwIDEzLC0xNzQgbCAxMSwtMTcwIDE3OSwtMyAxNzgsLTIgLTYsNDIgYyAtNCwyNCAtOSw1MTQgLTEyLDEwOTEgbCAtNiwxMDQ3IC0xOTYsLTIgLTE5NywtMyAtNSwtNzMwIGMgLTQsLTUwOCAtOSwtNzQwIC0xNywtNzYyIC0xMDIsLTI4NCAtMzY2LC00NDUgLTY0NCwtMzkzIC0xNzgsMzQgLTI5OSwxNzIgLTM1MSw0MDAgLTIxLDkxIC0yMiwxMjMgLTI1LDc5MyBsIC00LDY5NyAtMTk1LDAgYyAtMTU4LDAgLTE5NiwtMyAtMjAwLC0xNCB6IgogICAgICAgICBpZD0icGF0aDMxNjQiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2NsaXBQYXRoPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDMxNjYiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDE2MDM0LDIyMzYgYyAtMywtOCAtMywtMzQwIC0xLC03MzggNSwtNzg5IDQsLTc4NiA2NiwtOTc3IDQyLC0xMzAgOTIsLTIxNCAxODUsLTMwNyAxMjgsLTEyOCAyNTcsLTE4MSA0NjcsLTE5MSAyNDYsLTEyIDQ2Miw2OSA2MjksMjM3IDM2LDM2IDgwLDg3IDk4LDExNCAxNywyNyAzMyw0OCAzMyw0NSAxLC0yIDcsLTgwIDEzLC0xNzQgbCAxMSwtMTcwIDE3OSwtMyAxNzgsLTIgLTYsNDIgYyAtNCwyNCAtOSw1MTQgLTEyLDEwOTEgbCAtNiwxMDQ3IC0xOTYsLTIgLTE5NywtMyAtNSwtNzMwIGMgLTQsLTUwOCAtOSwtNzQwIC0xNywtNzYyIC0xMDIsLTI4NCAtMzY2LC00NDUgLTY0NCwtMzkzIC0xNzgsMzQgLTI5OSwxNzIgLTM1MSw0MDAgLTIxLDkxIC0yMiwxMjMgLTI1LDc5MyBsIC00LDY5NyAtMTk1LDAgYyAtMTU4LDAgLTE5NiwtMyAtMjAwLC0xNCB6IgogICAgICAgICBpZD0icGF0aDMxNjgiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2NsaXBQYXRoPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDMxNzAiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDE2MDM0LDIyMzYgYyAtMywtOCAtMywtMzQwIC0xLC03MzggNSwtNzg5IDQsLTc4NiA2NiwtOTc3IDQyLC0xMzAgOTIsLTIxNCAxODUsLTMwNyAxMjgsLTEyOCAyNTcsLTE4MSA0NjcsLTE5MSAyNDYsLTEyIDQ2Miw2OSA2MjksMjM3IDM2LDM2IDgwLDg3IDk4LDExNCAxNywyNyAzMyw0OCAzMyw0NSAxLC0yIDcsLTgwIDEzLC0xNzQgbCAxMSwtMTcwIDE3OSwtMyAxNzgsLTIgLTYsNDIgYyAtNCwyNCAtOSw1MTQgLTEyLDEwOTEgbCAtNiwxMDQ3IC0xOTYsLTIgLTE5NywtMyAtNSwtNzMwIGMgLTQsLTUwOCAtOSwtNzQwIC0xNywtNzYyIC0xMDIsLTI4NCAtMzY2LC00NDUgLTY0NCwtMzkzIC0xNzgsMzQgLTI5OSwxNzIgLTM1MSw0MDAgLTIxLDkxIC0yMiwxMjMgLTI1LDc5MyBsIC00LDY5NyAtMTk1LDAgYyAtMTU4LDAgLTE5NiwtMyAtMjAwLC0xNCB6IgogICAgICAgICBpZD0icGF0aDMxNzIiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2NsaXBQYXRoPgogICAgPGNsaXBQYXRoCiAgICAgICBjbGlwUGF0aFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIKICAgICAgIGlkPSJjbGlwUGF0aDMxNzQiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDE2MDM0LDIyMzYgYyAtMywtOCAtMywtMzQwIC0xLC03MzggNSwtNzg5IDQsLTc4NiA2NiwtOTc3IDQyLC0xMzAgOTIsLTIxNCAxODUsLTMwNyAxMjgsLTEyOCAyNTcsLTE4MSA0NjcsLTE5MSAyNDYsLTEyIDQ2Miw2OSA2MjksMjM3IDM2LDM2IDgwLDg3IDk4LDExNCAxNywyNyAzMyw0OCAzMyw0NSAxLC0yIDcsLTgwIDEzLC0xNzQgbCAxMSwtMTcwIDE3OSwtMyAxNzgsLTIgLTYsNDIgYyAtNCwyNCAtOSw1MTQgLTEyLDEwOTEgbCAtNiwxMDQ3IC0xOTYsLTIgLTE5NywtMyAtNSwtNzMwIGMgLTQsLTUwOCAtOSwtNzQwIC0xNywtNzYyIC0xMDIsLTI4NCAtMzY2LC00NDUgLTY0NCwtMzkzIC0xNzgsMzQgLTI5OSwxNzIgLTM1MSw0MDAgLTIxLDkxIC0yMiwxMjMgLTI1LDc5MyBsIC00LDY5NyAtMTk1LDAgYyAtMTU4LDAgLTE5NiwtMyAtMjAwLC0xNCB6IgogICAgICAgICBpZD0icGF0aDMxNzYiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2NsaXBQYXRoPgogIDwvZGVmcz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgb2JqZWN0dG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBndWlkZXRvbGVyYW5jZT0iMTAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE5MjAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTAxOCIKICAgICBpZD0ibmFtZWR2aWV3MzA4MSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMC45NjUzODc0IgogICAgIGlua3NjYXBlOmN4PSI3MjQuNTI3MjIiCiAgICAgaW5rc2NhcGU6Y3k9IjMzMy4xMTQ1MSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iLTgiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9Ii04IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMzAzNSIKICAgICBmaXQtbWFyZ2luLXRvcD0iMCIKICAgICBmaXQtbWFyZ2luLWxlZnQ9IjAiCiAgICAgZml0LW1hcmdpbi1yaWdodD0iMCIKICAgICBmaXQtbWFyZ2luLWJvdHRvbT0iMCIgLz4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGEzMDM3Ij4KQ3JlYXRlZCBieSBwb3RyYWNlIDEuMTEsIHdyaXR0ZW4gYnkgUGV0ZXIgU2VsaW5nZXIgMjAwMS0yMDEzCjxyZGY6UkRGPgogIDxjYzpXb3JrCiAgICAgcmRmOmFib3V0PSIiPgogICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICA8ZGM6dHlwZQogICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICA8L2NjOldvcms+CjwvcmRmOlJERj4KPC9tZXRhZGF0YT4KICA8ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDAuMSwwLDAsLTAuMSwtNCw1NTcpIgogICAgIGlkPSJnMzAzOSIKICAgICBzdHlsZT0iZmlsbDojMDAwMDAwO3N0cm9rZTpub25lIj4KICAgIDxwYXRoCiAgICAgICBkPSJtIDQwLDQ3MDAgMCwtODcwIDg3MCwwIDg3MCwwIC0yLDg2OCAtMyw4NjcgLTg2NywzIC04NjgsMiAwLC04NzAgeiIKICAgICAgIGlkPSJwYXRoMzA0MSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgZD0ibSAxOTMwLDQ3MDAgMCwtODcwIDg3MCwwIDg3MCwwIDAsODcwIDAsODcwIC04NzAsMCAtODcwLDAgMCwtODcwIHoiCiAgICAgICBpZD0icGF0aDMwNDMiCiAgICAgICBzdHlsZT0iZmlsbDojYzAxZDJlO2ZpbGwtb3BhY2l0eToxIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBkPSJtIDM4MjcsNTU2MyBjIC00LC0zIC03LC0zOTUgLTcsLTg3MCBsIDAsLTg2MyA4NzAsMCA4NzAsMCAwLDg3MCAwLDg3MCAtODYzLDAgYyAtNDc1LDAgLTg2NywtMyAtODcwLC03IHoiCiAgICAgICBpZD0icGF0aDMwNDUiCiAgICAgICBzdHlsZT0iZmlsbDojYzAxZDJlO2ZpbGwtb3BhY2l0eToxIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBkPSJtIDQwLDI4MDAgMCwtODcwIDg2OCwyIDg2NywzIDMsODY4IDIsODY3IC04NzAsMCAtODcwLDAgMCwtODcwIHoiCiAgICAgICBpZD0icGF0aDMwNDciCiAgICAgICBzdHlsZT0iZmlsbDojYzAxZDJlO2ZpbGwtb3BhY2l0eToxIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBkPSJtIDE5MzAsMjgwMCAwLC04NzAgODcwLDAgODcwLDAgMCw4NzAgMCw4NzAgLTg3MCwwIC04NzAsMCAwLC04NzAgeiBtIDEwMzUsNjMwIGMgODAsLTMxIDE1NCwtMTAyIDE5MSwtMTgzIDI1LC01NCAyOCwtNzQgMjksLTE1NyAwLC0xOTAgLTc0LC0zMTggLTM0NCwtNTkyIGwgLTE3NCwtMTc4IDI3NiwwIDI3NywwIDAsLTgwIDAsLTgwIC00MDcsMiAtNDA4LDMgLTMsNTYgLTMsNTUgMTgxLDE3NCBjIDM1NSwzMzkgNDUyLDQ5MyA0MjMsNjY3IC0xOSwxMDYgLTcxLDE2MiAtMTcyLDE4NCAtOTIsMjAgLTIwMiwtNiAtMjkzLC02OSBsIC00NiwtMzEgLTI2LDU4IGMgLTE0LDMyIC0yNiw2MiAtMjYsNjYgMCwyMiAxNDcsOTkgMjI4LDEyMCA4MiwyMSAyMjEsMTQgMjk3LC0xNSB6IgogICAgICAgaWQ9InBhdGgzMDQ5IgogICAgICAgc3R5bGU9ImZpbGw6IzEyNzNiODtmaWxsLW9wYWNpdHk6MSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgZD0ibSAzODIyLDI4MDMgMywtODY4IDg2OCwtMyA4NjcsLTIgMCw4NzAgMCw4NzAgLTg3MCwwIC04NzAsMCAyLC04NjcgeiBtIDExNzgsMjQyIDAsLTM5NSA5MCwwIDkwLDAgMCwtNzAgMCwtNzAgLTkwLDAgLTkwLDAgMCwtMTcwIDAsLTE3MCAtODUsMCAtODUsMCAwLDE3MCAwLDE3MCAtMjkwLDAgLTI5MCwwIDAsNjMgMCw2NCAyODEsNDAxIDI4MSw0MDIgOTQsMCA5NCwwIDAsLTM5NSB6IgogICAgICAgaWQ9InBhdGgzMDUxIgogICAgICAgc3R5bGU9ImZpbGw6IzEyNzNiODtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgZD0ibSA0NzkwLDMxNzMgYyAtMjQsLTQzIC0xMTEsLTE3MiAtMTk1LC0yODggLTgzLC0xMTUgLTE1NSwtMjE2IC0xNTksLTIyMiAtNiwtMTAgMzUsLTEzIDE5MywtMTMgbCAxOTksMCA0LDI5OCBjIDIsMTYzIDMsMjk4IDIsMzAwIC0xLDIgLTIxLC0zMiAtNDQsLTc1IHoiCiAgICAgICBpZD0icGF0aDMwNTMiCiAgICAgICBzdHlsZT0iZmlsbDp1cmwoI2xpbmVhckdyYWRpZW50NTM0MSk7ZmlsbC1vcGFjaXR5OjEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIGQ9Im0gMTg1MTYsMTc0MyBjIC0zLC04MzUgLTksLTE1NTMgLTEyLC0xNTk1IGwgLTYsLTc4IDE3MCwwIDE3MCwwIDcsODggYyAzLDQ4IDksMTI3IDEzLDE3NiBsIDcsODkgNDAsLTU5IGMgNTMsLTc3IDE2MCwtMTgxIDIyOSwtMjIzIDEyOCwtNzcgMjQ4LC0xMTEgNDIxLC0xMTggMjEwLC05IDM4NywzOCA1NTIsMTQ3IDI3NiwxODEgNDM4LDQ4MiA0NzQsODc5IDM5LDQzMyAtMTA1LDgzOSAtMzc1LDEwNTYgLTE1NSwxMjUgLTMzMCwxODUgLTU0MSwxODUgLTE5OSwwIC0zNTcsLTQwIC00OTMsLTEyNiAtNzEsLTQ1IC0xODMsLTE1MyAtMjI1LC0yMTkgbCAtMzIsLTUwIC0zLDY4MyAtMiw2ODIgLTE5NCwwIC0xOTQsMCAtNiwtMTUxNyB6IG0gMTE1NSwyMjMgYyAxNDksLTMyIDMwNSwtMTQ4IDM4OCwtMjg5IDc5LC0xMzUgMTIxLC0zMTMgMTIxLC01MTIgMCwtMTk2IC0zNSwtMzU2IC0xMDgsLTUwMCAtNDMsLTg0IC0xNzEsLTIxNyAtMjQ5LC0yNTggLTc3LC00MSAtMTkyLC02NyAtMjk0LC02NyAtMTE2LDAgLTE3NywxMyAtMjc4LDYyIC0xNDYsNjkgLTI1OCwyMDMgLTMxNywzNzggLTE3LDQ5IC0xOSw4OCAtMTksMzYwIDAsMzA1IDAsMzA1IDI3LDM4NSAzNywxMDkgOTEsMTk2IDE2OSwyNzUgNzQsNzQgMTkwLDE0MSAyODYsMTY0IDc2LDE5IDE5MSwxOSAyNzQsMiB6IgogICAgICAgaWQ9InBhdGgzMDU1IgogICAgICAgY2xpcC1wYXRoPSJ1cmwoI2NsaXBQYXRoMzE3NCkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIGQ9Im0gMTQ2MTAsMzEzOSBjIC01MTgsLTY1IC05NDQsLTM1NyAtMTE2NCwtNzk3IC0xNDEsLTI4MCAtMjAxLC02MzYgLTE2NiwtOTgzIDcyLC03MTEgNDgwLC0xMTc3IDExNDcsLTEzMTAgMjExLC00MiA1NTcsLTM2IDgxMywxMiAxMTksMjMgMzIwLDg2IDMyNiwxMDMgNiwxNyAtNzIsMzExIC04MiwzMDkgLTUsLTEgLTQ5LC0xNiAtOTcsLTMzIC0xNDcsLTUyIC0yNjIsLTcxIC00NzAsLTc3IC0yMTAsLTYgLTMyMCw0IC00NTcsNDQgLTQzNywxMjYgLTcwNSw0NzIgLTc2MSw5NzkgLTE1LDE0MCAtNSwzODggMjAsNTE0IDYwLDI5OSAxOTgsNTM2IDQwMyw2OTAgMjIzLDE2OSA0NzIsMjM4IDgwOCwyMjcgMTg0LC02IDMwNywtMjggNDQyLC03OCA0NiwtMTYgODksLTMxIDk2LC0zMiA5LC0xIDMwLDQ5IDYyLDE1MyAyNyw4NSA0OCwxNTUgNDcsMTU2IC01Miw0MCAtMjc2LDEwMSAtNDU3LDEyMyAtOTcsMTMgLTQxNCwxMiAtNTEwLDAgeiIKICAgICAgIGlkPSJwYXRoMzA1NyIKICAgICAgIGNsaXAtcGF0aD0idXJsKCNjbGlwUGF0aDMxNzApIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBkPSJtIDczNzAsMjg1NSAwLC0xOTUgMjEwLDAgMjEwLDAgMCwxOTUgMCwxOTUgLTIxMCwwIC0yMTAsMCAwLC0xOTUgeiIKICAgICAgIGlkPSJwYXRoMzA1OSIKICAgICAgIGNsaXAtcGF0aD0idXJsKCNjbGlwUGF0aDMxNjYpIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBkPSJtIDIzODg2LDMwMjQgYyAtOTksLTE4IC0yNjQsLTczIC0zNDgsLTExNSAtNzEsLTM1IC0yMTgsLTEzMCAtMjM3LC0xNTMgLTEwLC0xMiAwLC00MCA1MCwtMTUwIDM0LC03NSA2MywtMTM2IDY1LC0xMzYgMSwwIDM2LDI0IDc3LDUzIDE2NiwxMTkgMzI0LDE3NiA1MTMsMTg0IDMwOCwxNCA1MDMsLTEwOCA1ODAsLTM2MiAxNCwtNDYgMTksLTkzIDE5LC0yMDAgLTEsLTE3MSAtMTksLTI0NyAtMTAwLC00MTAgLTEzMCwtMjYxIC0zODAsLTU0MyAtMTA0NCwtMTE4MCBsIC0yNTAsLTI0MCAtMSwtMTIyIDAsLTEyMyA5MzUsMCA5MzUsMCAwLDE2NSAwLDE2NSAtNjU3LDAgLTY1NywwIDEwOSwxMDEgYyA2MSw1NiAyMTgsMjEwIDM1MCwzNDMgMzQyLDM0NSA1MTgsNTYzIDYzNCw3ODYgMTc5LDM0NSAxOTgsNjc4IDU3LDk2NSAtODEsMTYzIC0xODgsMjcwIC0zNTEsMzUxIC0xNDEsNzAgLTIxOSw4NiAtNDI1LDkwIC0xMjUsMiAtMTk4LC0xIC0yNTQsLTEyIHoiCiAgICAgICBpZD0icGF0aDMwNjEiCiAgICAgICBzdHlsZT0iZmlsbDojMTI3M2I4O2ZpbGwtb3BhY2l0eToxIgogICAgICAgY2xpcC1wYXRoPSJ1cmwoI2NsaXBQYXRoMzE2MikiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIGQ9Im0gMjY2ODEsMjk3NyBjIC02LC04IC0yOTksLTQyNSAtNjUxLC05MjggbCAtNjQwLC05MTQgMCwtMTMyIDAsLTEzMyA2ODAsMCA2ODAsMCAwLC00MDAgMCwtNDAwIDE4NSwwIDE4NSwwIDAsNDAwIDAsNDAwIDIwNSwwIDIwNSwwIDAsMTU1IDAsMTU1IC0yMDUsMCAtMjA1LDAgMCw5MDUgMCw5MDUgLTIxNCwwIGMgLTE2NiwwIC0yMTYsLTMgLTIyNSwtMTMgeiBtIDcxLC0xMDg0IC0zLC03MTMgLTQ4MCwwIGMgLTM4MiwwIC00NzksMyAtNDczLDEzIDUsNiAxNjYsMjMwIDM1OCw0OTcgMzQ3LDQ4MSAzOTksNTYwIDUzMCw3OTggMzgsNjggNjksMTIyIDcwLDEyMCAwLC0yIDAsLTMyNCAtMiwtNzE1IHoiCiAgICAgICBpZD0icGF0aDMwNjMiCiAgICAgICBzdHlsZT0iZmlsbDojMTI3M2I4O2ZpbGwtb3BhY2l0eToxIgogICAgICAgY2xpcC1wYXRoPSJ1cmwoI2NsaXBQYXRoMzE1OCkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIGQ9Im0gMTE5MjcsMjI4OCBjIC0xMDgsLTEwIC0yNDgsLTU1IC0zNDEsLTExMCAtODIsLTQ4IC0yMDMsLTE2MCAtMjQ3LC0yMjkgLTE3LC0yNyAtMzQsLTQ3IC0zOCwtNDQgLTMsNCAtMTAsODIgLTE2LDE3MyBsIC0xMCwxNjcgLTE3OSwzIC0xNzgsMiA2LC00NyBjIDQsLTI3IDksLTUxNyAxMiwtMTA5MCBsIDYsLTEwNDMgMTk5LDAgMTk4LDAgMyw3MjcgMyw3MjggMzEsNzIgYyAxMTMsMjYwIDM0MSwzOTggNTk4LDM2MiAxNjQsLTIyIDI3NiwtMTAzIDM0NiwtMjUxIDczLC0xNTQgNzIsLTE0OCA3NywtOTM1IGwgNSwtNzAzIDE5NCwwIDE5NCwwIDAsNzIzIGMgMCw3OTYgLTIsODI0IC02Miw5OTcgLTEyMSwzNDcgLTQyMCw1MzMgLTgwMSw0OTggeiIKICAgICAgIGlkPSJwYXRoMzA2NSIKICAgICAgIGNsaXAtcGF0aD0idXJsKCNjbGlwUGF0aDMxNTQpIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBkPSJtIDczOTAsMTE4MCAwLC0xMTEwIDE5MCwwIDE5MCwwIDAsMTExMCAwLDExMTAgLTE5MCwwIC0xOTAsMCAwLC0xMTEwIHoiCiAgICAgICBpZD0icGF0aDMwNjciCiAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgzMTUwKSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgZD0ibSA5MTk5LDIyODAgYyAtMjIwLC0zNyAtNDE4LC0xMzggLTU3MCwtMjg5IC0xNTAsLTE1MSAtMjQyLC0zMjkgLTI5NSwtNTcxIC0yNiwtMTE5IC0yNywtNDI5IC0xLC01NDcgNTIsLTI0NCAxNDksLTQyNiAzMDUsLTU3NSAxODcsLTE3OCAzOTYsLTI2NCA2NjgsLTI3NSA1MDAsLTIxIDkxMiwyNTEgMTA2NSw3MDQgNTQsMTYxIDY0LDIzMCA2Myw0NDggMCwxNjcgLTMsMjE1IC0yMSwyOTEgLTEwMyw0NDEgLTM5MCw3MzAgLTgwMyw4MDggLTg3LDE3IC0zMjYsMjAgLTQxMSw2IHogbSAzMzQsLTMwNSBjIDI1NSwtNjYgNDM4LC0zMDggNDg3LC02NDQgMTcsLTExNiA4LC0zNDMgLTE4LC00NDIgLTY0LC0yNDMgLTE5NywtNDIzIC0zNzQsLTUwOCAtMTA1LC01MCAtMTg0LC02NiAtMjk2LC01OCAtMjIxLDE1IC0zOTMsMTM2IC01MDgsMzU5IC02NiwxMjkgLTk1LDI1MCAtMTAxLDQyNSAtMTEsMzA4IDY3LDU0NSAyMzYsNzE0IDgxLDgxIDE1OCwxMjYgMjYxLDE1MyA3MywxOSAyNDEsMjAgMzEzLDEgeiIKICAgICAgIGlkPSJwYXRoMzA2OSIKICAgICAgIGNsaXAtcGF0aD0idXJsKCNjbGlwUGF0aDMxNDYpIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBkPSJtIDIxNzUwLDIyNzUgYyAtMzUyLC03MCAtNjExLC0zMDUgLTczOSwtNjY4IC01OCwtMTY1IC03NSwtMjcxIC03NSwtNDc3IC0xLC0yMDQgMTAsLTI3OSA2NiwtNDQ3IDExOSwtMzYwIDQyMCwtNTk4IDgyNiwtNjUzIDEyNywtMTggMzkyLC04IDU0MiwyMCAxMjIsMjIgMzYwLDk2IDM2MCwxMTEgMCwxOCAtNjMsMjY0IC02OSwyNzEgLTMsNCAtNTEsLTggLTEwNiwtMjcgLTE1NCwtNTEgLTI3MiwtNjggLTQ3NSwtNjggLTIwMywwIC0yNzgsMTUgLTQwOSw4MyAtMjE0LDExMSAtMzI4LDMwMiAtMzU2LDU5OCBsIC03LDcyIDc2NSwwIGMgNjg4LDAgNzY1LDIgNzcxLDE2IDEyLDMyIDYsMzAzIC05LDM5MCAtNDMsMjQ0IC0xMzQsNDMzIC0yNzcsNTcwIC0xMTUsMTEyIC0yMzUsMTc0IC00MDAsMjA4IC05NCwxOSAtMzE0LDIwIC00MDgsMSB6IG0gMzUzLC0yOTUgYyAyMDcsLTY0IDMzOCwtMjU3IDM2MywtNTM1IGwgNywtNzUgLTU3NywwIC01NzYsMCAwLDIzIGMgMCw1MiA0MiwxODcgODYsMjc1IDgyLDE2OCAyMjcsMjkyIDM3NCwzMjEgMzAsNiA2NCwxMyA3NSwxNSA0MSwxMCAxODUsLTUgMjQ4LC0yNCB6IgogICAgICAgaWQ9InBhdGgzMDcxIgogICAgICAgY2xpcC1wYXRoPSJ1cmwoI2NsaXBQYXRoMzE0MikiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIGQ9Im0gNDAsOTEwIDAsLTg3MCA4NjgsMiA4NjcsMyAzLDg2OCAyLDg2NyAtODcwLDAgLTg3MCwwIDAsLTg3MCB6IgogICAgICAgaWQ9InBhdGgzMDc1IgogICAgICAgc3R5bGU9ImZpbGw6I2MwMWQyZTtmaWxsLW9wYWNpdHk6MSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgZD0ibSAxOTMwLDkxMCAwLC04NzAgODcwLDAgODcwLDAgMCw4NzAgMCw4NzAgLTg3MCwwIC04NzAsMCAwLC04NzAgeiIKICAgICAgIGlkPSJwYXRoMzA3NyIKICAgICAgIHN0eWxlPSJmaWxsOiNjMDFkMmU7ZmlsbC1vcGFjaXR5OjEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIGQ9Im0gMzgyMCw5MTAgMCwtODcwIDg3MCwwIDg3MCwwIDAsODcwIDAsODcwIC04NzAsMCAtODcwLDAgMCwtODcwIHoiCiAgICAgICBpZD0icGF0aDMwNzkiCiAgICAgICBzdHlsZT0iZmlsbDojYzAxZDJlO2ZpbGwtb3BhY2l0eToxIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICA8L2c+Cjwvc3ZnPgo=';
header('Content-Type: image/svg+xml');
header('Cache-Control: public');
echo base64_decode($img_encoded);
}
%PDF-1.4
1 0 obj
<<
/Title (�� M a r k d o w n T o P D F)
/Creator (�� w k h t m l t o p d f 0 . 1 2 . 4)
/Producer (�� Q t 4 . 8 . 7)
/CreationDate (D:20251014155653Z)
>>
endobj
3 0 obj
<<
/Type /ExtGState
/SA true
/SM 0.02
/ca 1.0
/CA 1.0
/AIS false
/SMask /None>>
endobj
4 0 obj
[/Pattern /DeviceRGB]
endobj
8 0 obj
[0 /XYZ 33
813.500000 0]
endobj
9 0 obj
[0 /XYZ 33
749.750000 0]
endobj
10 0 obj
[0 /XYZ 33
700.250000 0]
endobj
11 0 obj
[0 /XYZ 33
115.250000 0]
endobj
12 0 obj
[0 /XYZ 33
296 0]
endobj
13 0 obj
[0 /XYZ 33
80.7500000 0]
endobj
14 0 obj
<<
/Type /Annot
/Subtype /Link
/Rect [71.2500000 50.7500000 144.750000 59.7500000 ]
/Border [0 0 0]
/A <<
/Type /Action
/S /URI
/URI (https://ioncube24.com)
>>
>>
endobj
5 0 obj
<<
/Type /Page
/Parent 2 0 R
/Contents 15 0 R
/Resources 17 0 R
/Annots 18 0 R
/MediaBox [0 0 595 842]
>>
endobj
17 0 obj
<<
/ColorSpace <<
/PCSp 4 0 R
/CSp /DeviceRGB
/CSpg /DeviceGray
>>
/ExtGState <<
/GSa 3 0 R
>>
/Pattern <<
>>
/Font <<
/F6 6 0 R
/F7 7 0 R
>>
/XObject <<
>>
>>
endobj
18 0 obj
[ 14 0 R ]
endobj
15 0 obj
<<
/Length 16 0 R
/Filter /FlateDecode
>>
stream
x��][��6�~�_��"��(R�a��n/��,`�<��p�
I�d���W��t�XU_S����V�ؤ���s�����_���g�����7����P�F�Y��N�6w�3+���}���=�~�t�����aX�_��~?��w����_ͷ��d��Ϳ����������v0����B7����(���Em�ߋ�?�?���d�7�(r[R*�D��ɿ���[=y˼�*M�m�]�.D]�ߕ�5Z��}٬���e������+?N�:��~��q�ٮ1z�+12���)u���?�f�����>|9��X5�!��sֿ��Ǘ?�*��c�����/�8T��BꞼ�ٍ�וm���FJe�s�~��RL���~�y�FL��=<��~�̭���v]ϞS�����~���p�[�K��؍�y�?�]8>g:�G>v#&W�V�Q�9pB''t5zS!�7��vP�U���0�`�={r�K���_����翾������}��{�=|xl��?�H�']�{�<O}<<}9e��iˌm6ѱ.!�2rx�ҝ�� 4�{�����{g��S8�����s���gpj XMνV��s��3��]�+E��w��G��~)�Z�>j�M�0D=0�q�̋rJg���j�¾lon|��a����3j��g�ہ�����x5k�j�|�%p���jN)<X�g~��Rxn�pK�x�Bc/��G1u�p#`�?��b���k���x�={��73������ݜR+q!���Q��znc��f�6��5��g���?x5|�7�@�� YS$�7z�L,���(��r2�K6�SX�9�]3�7#0��pcd
B��&�ZY��K�x����f14$�m�ȣ-�
=�����$�9�_��{�N��A<����w�R)a�,
��Z������g��o��[�Z��[|�a54|�0�ݵԎ^W�wp^c��f�$ǿQM��4r�H@BE �tk$�0���9+��zq9�Ü��N:g�ܵ�Y�9+m�&N7�0�z�����<Ι�~S��zA���a�Y
Úy���w?.���y���q�!h��U/ٛ�� ���(II7!݄Wu�t���6��MQ�UY\�k�&t ��ѧ��=�,Z�Ms���|<�tFs�Z-��`�b|��bX��\���a����`;�^l�Qb8�+�ڰqV��wnE[��̈�A�{ Ȑ�!�;6�Q�F���C7;�\_XX��CI';�}��0�,h��>�w���(r�M���g�82���nd�Ig�
R��-���!.��9��'�!�Ů%��Tq"�Nc��J+��.��n��B5Ǫ��3+�ͤ�3Q������b �T�U�y0z����|D���h8R�G,���yG��=�ƫ1��oʼ���<���F\V�҈X[gm�=>�J&�������}�\|z?9�O\�������&|!��1i1a,���,?/���KpUqt"3Y�w�{�Q@D&����p�g�hļO��;���0z`4ox�l�X�9�-�5�A��2�����ň�^����TX?�[X��`��o4���&��=���@$��XM�ޞ3�
��ǃ��L�T(A����e�n���+�vS֧��7����E��\KL�q,����j�AY!��D��� ŬZY�
��HK��aB�TcI�#���WK�LL�9�Iƞ���ă^�='&�9�p�rEb&ň�ݦ
7��8>��h���ŭoREK�z1�1�c��{�I2�����S�1�j;k<^5E�+��AK1R��1{N����j)���� �T�n����Ѥh1ʆ;��_�\�.p��5�0����ʁ��7����⻞c
k4�7�)�4�9 #p����i�bi���8�.��2j��.
lO�� Q�VX�\�����n6D'O`܀�8-+}3-��t���4J�B{J1r<Ѫ��u��mC_���"�o��oo�
,�0q�L�-C��
4�K�DJ�-���]T#�_�MV��^L��Y�"���cV�c֫sy�1�
��Ռ"ֿ�Pu�ٰQ.��p5��/0oe2J��)G�^���9�TM�&��cE�HkY�?��v�p[ڸb���G�Zq�z�=0#B��`�옘ΰu&~6V^��� ��,��C\�|pOڠ� g��,��w�ݙ"Su��j��ΨSL�T�:7�"27����:#Q��A��u�vhv��D)F��Jӥ�t��ui:%���Nx��n+��V��J���/�@[���3U�oe�k��u�J�֥*�����T�V�W��2��Z����g4���$����𗕠�jt�18W���/��T�'4�%pF��$�0{c���a;A)P���R�L��d���L�ef��!BA��(bP#�9�%{�8��g���E,���3P����w�F"���R��l��ޯ�hU��z�.�s|+�8��DK-ـ�`}��S���rI�U���j��$խ��<�^�ylݭ�|�u��w3�d�Zk�<�4\(l�
���ݏ�V[��!�[1y��côK��_�}����LP9��E}�(�R݀�}�s~}��D_^�0H8G)O� �k���u���PL��jxN�Q��WuiTdž÷�^�1R���h����TG]��Qw���Hu�~7�Iƭ��ꨟ2 �{w\��6s���E��v���1��q$���Fm�Hn9Se��� i�Sd�x��GN�qQXfg�,�`��M����f�j��ހ绳3� )z=v��A
7Q�De^HeVӠ�F����R-hPUaZ���iP��j4IukuTU�
�������nF��[ke
�R0��C.G:h��=��OC��[\
�f<)zA��d��
oB��T��Jb߅;�MgUR&V��*�x��Wxwp� vV�QZ*1XUK�U�+�$b��]�&�n�^i�K�ͯ�Zz1�nF��[km��J�'s6W��ҫw�2�:2qs�%�O��?Aa�^���S��PD�IU���-�0��P�W爅.<�m�X�|mBqXU+���SM��΄�R��q�/�ߞ�hF��_х�6ˀ��{I��-�r5�f�Y���̫ˢ�7�n���*O��Jjy�u*�u�%�d[U��0u��B�a�'CVB��$�eپ���l!�G���
w���bܻ�oZ�nlPY�C� ��X�|�E�@�V}��t���Tw��xSK��
T>jK4͑5V,h`� �0��ow�"�ds瑫��'3B��-��2����8��C��ô��b��Y6^"�=I�L}3串K��U���V_ޥ�e�%~�=9^�JT����`�4�Tu�ch�r�i�t�<�8�;�螣gƃ(�c�Q�2�ԟ_v�R�QG���yEk�����+3Z݄ ����<���hJ1��{���� 0�{�+'���s���� >&��\��%��99��E%i�Ӌ��2���1Ċ%b@'��t���СH:ܛgױJ1W�2RAe�X��6s�qw����mHM��zm�"�ٞ�+����ȞW�N��P�3/�>�>�{B��� ��"mN��,\N'b�;���L�xB���a�vN=Xٺg�:��E�h�Y$�cI=Z����R9�k��U�`r�ƱB��*,��#�Q
%\����z��y.��� &��H��8Mm2y��6��+����"��w�������S�c�@���ow
hE���FZ�Xy�~�(`�����#�)H|
�f���
o��1�XN �D� p���r�^;�l����g�}���c�&lM:72.����VҔm�e�}$�\��A�C��� ���(���`�tn�I�㨰��|��6/�B��*�� ��7�>e>��<#3����W,a��z�
��c��e��j�S�ρp���:�҃�9�.0~�`0a����O����>�9��{�v�°f ʼ����{sg:�o>�������o���_~�����wٻw�Çǃ�Kg�L$Q�DA9<����ā��Z��6S�Q�a��ۧ`z�cLbW��
nx�}ʸ��vLp��,-W��l���8�z0��O�[�𤰁a�k0�aں2�Z68#hJ��|��� L��PasH���n3<8��U��ac�
����R��y
T�� (^{2���$÷����K�(�1I0�"rN�ΰ�|��������`\�~l7<�ɔ-=5�a/d�:�u�=��S�t�=w�1�1;���(��F�}S�!!�dd2E�7ũJ�`L5 �l#T���H���WX�lX�U}#1�hu�+4c��5#�3d�(ͪ����LJ�z��0�`��7
��ĸiUغ�>9�:A>�"�Y�f�϶6� S�đɼ����
0n&F�<����.Z���>�0�G$(ԭ�,㛹����kS/4s�m�6`o?F�ܻ��h���ꚹצZh��ڭ�|���w���$��Z��{�\�`��l7&ߑ���ֆ�f#YSwR�\]��i�n���;صm6��M���V-%�]-�����Z�� M�Z�iŪ�s$��#j4O��uRZ��q6���zj,��#f4��,�5OJ�$Q-�j�iՒ��D���m&DfςC����,()9J�<� (��l�ω�Ԏ��<կ�%U, J�p�SA��a��3�z�Jj�\��$(�'�����$Q�D�D��3n�fցc>��ɉ��bM� у]�O�)���D�x� lϓ��
�}�s� ���1�O��� ������ z�t��bS��SAU,�
*ѫ����TЎ��<կ�L�,�
���h35�#f4��n*���k�T�D�D�d*H����=Ģm5�hk�X��=K�vʢ�5����������;`�)�nG�h��[�E�ǃM,z�V��S̛�6B��9L`��I�C�g�#�&�n����yu!��\�PNp�\\�Н��~��nD��~�^pm�[\���zb"�v#f4��-�
a���Ebֱ�P���u綥$���*[�]��xf���R, J���RN�vD��~='()�$(��b�~N�vČ�a����L��˘C���9��E�n"K��#����Ibdk]5��I<ݵx��O��mj+�nu�ߟ��oG��~�N��}3C�'��Y E�Fv.tTf��5&/@��f3\?����q�A�WSO����pf�/Zm�ⴹ��%��0��q���h�]K=����զԝv��IwT�ގ2�^�k���
�܁:�|�l`P���E:�=�!:;S|
O
�j���V�9�����6��9A)�{��Q��)���uE�����Kl.������;�;��RaR��*�;�3%�a��33V�`ٟ��V�=,U�`�EF<�Undn6��7g���Ѥ3u.8à��Z��r�0��(0t.<ǹ7,lb��>��qg�y��<��;9'�\�75�Vۉ���3#�7�g���z�x�w�w-�]C|��@�$���kx>.�aa�M=x=�@�n0�%�=�Y
�
��x�j��r�} 0��::3�~<�Eu�"8��A�H#1��0�H��Q��$`*p�!�z�%O;�ZKf�"b�-Qi�S���:�;�]B��4�n�����ܪ��F5��.����u�������t���� ���iPM�W�̝)��]u�}{��q�|��MH���'),sqE�;�x4T���=S�tʉ��3e���U���LP�+�{��U�-lX#C(���L�-S��j��)�u>c�K�_��o!�W;V�tr�X] ��A3h�HOO�F�?p�3��N��j�~�TQ"��`�����ĞR�Xa`�����x'b��2�V1��7y�n�ZTb�����UJb ����ђ@��sO���v�i��}��9�<ɸ��}:�?Eg(
endstream
endobj
16 0 obj
6152
endobj
20 0 obj
[1 /XYZ 33
735.500000 0]
endobj
21 0 obj
[1 /XYZ 33
647.750000 0]
endobj
22 0 obj
[1 /XYZ 33
134 0]
endobj
23 0 obj
<<
/Type /Annot
/Subtype /Link
/Rect [102 671 175.500000 680 ]
/Border [0 0 0]
/A <<
/Type /Action
/S /URI
/URI (https://ioncube24.com)
>>
>>
endobj
19 0 obj
<<
/Type /Page
/Parent 2 0 R
/Contents 24 0 R
/Resources 26 0 R
/Annots 27 0 R
/MediaBox [0 0 595 842]
>>
endobj
26 0 obj
<<
/ColorSpace <<
/PCSp 4 0 R
/CSp /DeviceRGB
/CSpg /DeviceGray
>>
/ExtGState <<
/GSa 3 0 R
>>
/Pattern <<
>>
/Font <<
/F6 6 0 R
/F7 7 0 R
>>
/XObject <<
>>
>>
endobj
27 0 obj
[ 23 0 R ]
endobj
24 0 obj
<<
/Length 25 0 R
/Filter /FlateDecode
>>
stream
x��][o�F~ׯ������0$���] ��}X�C�[Mд)�?Iq(�����pHZ��X���p�̹|�v��������-y���?�Ժ�T�/����¸���8m�����[�m�a����۪�cs��_W7ͳV�o>�����$��~�%���o?���?��*t��o����_��*��y�KW�^�X��ϫ�-�Z�C��R�Xcu3���o�.�^�����K]�i�2W6YZ*]�g[4?un|�]��B'�Uo���y�S��ݣ�363e���շ�L�G��)[��>�(���6���{��hS�<֣u��z�=|�C�&�;M!���iu�'�$O?%��4ߞ�I���TLn�J�]��˪X�&kY3���H5SU��loD��j��v�Xt�*��M7{#���t]���^��_��l��H�G
������͈�����?�k\{��� �5��~��ލ<nF*�u��������wh�#�εb�6���vO]���Pt��>?��a
���T7�Ѫ��#̺�g}�@�bV�����2��5��if��s�<�9>W��x�Y��{H����*�bm ��}}�<�'6Oչ's����ϖ?�!�k1��7
<sTH��$�a|3���y�.�Mz!���B������p����4^�G��l缩iw��݈5�M�})�a�D��S��*F�A$ n��H�V=n��<����್�����)�|�� �)�;�9���l���D�f�)a���� E2�,�n���tMxx���K
��LTal�h��(��9T���p��Lе��5~h7b��O0�Vz���y֚�w�V��V�MuGv(�\A["}7����hM�� QF��n��_��6F�b8�c�)7�cy
��x�#x�5�PO�9��?���X`x�� �����L�Y��a�O�)%S��f,~Q\Lx�1��xu��l�GT���v[��&��#��I�����c'#s�V���)/����p>a$o0K|"`1z�D|���H&���CU�W�Ɛ��U��O��/��R�?�s�+��&*K(T���2'���(��a����l����u_$�k��-�^٘�}�SO���#�gs>��û1�T̬�� �(�발�䉤P0�ȵX�O��@s^[eQ�`�[��E�:��d�R��2���J���`��`k�0/YD��9�k��iY$U4_���0�Cd�QQ]��~�X�ڱ8��iTmU�Y}&� �F87��@�
�(���(�cra~@� 3xco�1/8k�I�)�a>*J��@�����.��GeRL�f2PD�*���Pq��.0�F�,W"���442��霣�#u�\����ȔX�3�<�V'Z&��і�9ڱP Y�������s��"���ܩ9v�ߟ��>�sj�!�����h�>�z�vN5rh��k��eG·�#~�{;S?���9�8?��T2ݙ���se���������>�Ҏ�����V�|�����6�y����O�>}��{r{���%���W&A�OͲ�S�҇�HO�N!˔^L�C�?67Q �)pEi��#����W�!��o*�L:�0R!�hf9J�ך�
���!vTq�yT�n�֍��h�a�T �@���pT�b�� ����]���D�
����M� 0Sg�l�قN��%a�`� �28@4]�
pdR�e9�G�u�d:?M�xo���L�T�M��0�U�`�p�,���[T�w6�
H��r1%I#��>)��J�C��T�u'���K�����q���p{\�� �kc��N��`9 w�Z�-죧�^P%n�A����B-��KG��M�wh��ݘ�L�U�6/T;"�
%"�F(�u���u�Y����fb�-b��1zd��|&�%V�2��3e�g�#1�$?LU��
��"�-P>Q4e���T�ה�O0�Kj��=�6F�](|!r��v&���X�\b5��0�v]�
�˶��d 7I�� HE+1R��A )ύh�ByFfT]�O���\m�Ŷk��n��_1��ǽ'7�6����;� ܺPɣ��lO�a©�En�'��M�N�ޙ�M�6�?���f�s|�o�Y6tڿ�Z6n܍5@:�-�j����{��>��zD�68��a����)ˍ�9S.L�����?;�xb:��bЮF��rw~����R�.y����X�]���ꮿ^��'p�m����O�;�ZOF��H�ȶ�g��wsp_c��[8�-Yp��pl�
_��C.��#���9�}���ٝѴ�����F?ɸ�� �u.?+[�1Z�ѶX٢ L���L1
��X��Q���ms1dN���<1;YO.�Q���ZZ�iDia<bu;"Q�r�i�B��'��
���ƴ�X���ĉ0��#���?��UR+�nQl�m3e��[q�A&���VŜ0&]cLE�`L�� �1���%��B�@�1�,S�91�
�#� 0|���5<���7
�`��G�
��@6(����L;x
H_C�0؏���QĞ���7}�"���{]�#�Ӟ�\8��Ikc�e�=3P
�T"Z
� y��"u1g��B�cՈ�o:a�a�����h�)�G?\�v�߱2~�p,O8)��>����ee�,f�½b��2��&�d�"�K�P.�Y���u<gY�N+��N��!T���0s��5XbM�k��kھ�� S�h�P�!P ���(�Ѫ��^;�����?��0�F𬉸� �Vb4`���Z�nc����� [Mai�I�%2Q�LGf�cE�^MS��.A�'0CL��XN�ޘ7%�cћp��H�c��/���֙���gM9��̂@MF知ԏe
��Ds�N:���ǼitGo Y�,�$)�q>Qal�:U��J��(�J�Y毾��ʯM�~A�aqS�*/��3E=��Ȥ�fi1
�1��U͙ڀ�=h�7�9��/*V�z�:��|`�a�(�Mj���e�G�S����h�p�)㫲=����b���(�0�@T$
&-�b%<0����E)d�x�X� ��NR��6�H��{�LZ�-~�W�7��;�*����4��uh�DoQ�%!V���벖��9�p�o���\vR,�1�'�U����%���$�h�|g`��p�N�Uh�"Y�jK �H3YRm����l]�yv=�6��j�>��C�("V�0��JQ����c�qr3�=�3p��h�8�ba��Y�P�,k�2���le�ӶNc�f��������f)9��r3)k�A�T�F�1-&잠@T����HY�&��L{�X�"5��PU����0W�����U��M�Q�>w���ZN0ኯ�f&
=P��$p�ҁ$�N-꘠�F��IWa�zeyqJ(�䵭5S@`r�D������7Q�
�ں��k�K��]˺��^&�s-�h|�r��!ny��b�3;B��`W����y«3g��ЬӶ�ܮ�}g2�)����c��'�N�}���d
�X���9R Hͩ��9w�hN|$ٕo˭�F�����L&�NdS
4^Y��j>\���`�ab��E�F�t2&,��3�̰wy��a�!�T�
��9���a4�.ѲK��Ξ�&+��)p.�p�`T�.`j�At�&�&_n)���
��e:K#��G�bC�.1Ve��j�k���q?�цF�q���u��6F��cF�s�Q"ޅ!(q`�m��^��Fv���&5[��(�8_��zO����yc6�����ax�x�+�i���xu��Y�LK@�fvJF��7]r�C�c���PF-\�+̮����!Z&����C���'�u?5 �a`��_E�d��d��>���x��8�)�=KתlS�h%I1�̈́�I��#c��̺a��g&�sw�c����i��s�p?��Ok�>��ks��fmةo[]�Swf֬�k���x�[{O@OssG\P�^V� Ǯ���<���8q�늯d� � ��[47O�n]����Y��x<���<����f
�ǟPw��{?�d�!Q�|�����6�y����O�>}��{r{���%������K.Ļ������P�|��AH�N���O�b�u<���c�~�����~|7�c��0 �� � �}���7Ş�����g�u�wH36bl�AB%GDU(ۜ�T6�6��
���W�"�T��9zb�%F ��m�nA#۴��](���C���%�MX��^�1$����[Y0Y�/�S����2�y�L��*�Y�ye+K���M��f�v���꿫?��'���_�����'�#E红��ϫw���
q�/k�Ez���]f0
� �U-#���:h[�������fz,�p F+�ɭ6~�����yE�^k�0ʰ!
'R���d�1sG��V��wY#�������ls?/�>&�Ӈ�):���n� �r�f�F�0PLiY�?Fs��8*�V7.��ƹjt�{��lFl�:�����n\zݸ��ƥˎn\�Ѝs�������
Q7)@ܓ"��+�ܑ�V�����0WfV
endstream
endobj
25 0 obj
4671
endobj
29 0 obj
[2 /XYZ 33
106.250000 0]
endobj
28 0 obj
<<
/Type /Page
/Parent 2 0 R
/Contents 30 0 R
/Resources 32 0 R
/Annots 33 0 R
/MediaBox [0 0 595 842]
>>
endobj
32 0 obj
<<
/ColorSpace <<
/PCSp 4 0 R
/CSp /DeviceRGB
/CSpg /DeviceGray
>>
/ExtGState <<
/GSa 3 0 R
>>
/Pattern <<
>>
/Font <<
/F6 6 0 R
/F7 7 0 R
>>
/XObject <<
>>
>>
endobj
33 0 obj
[ ]
endobj
30 0 obj
<<
/Length 31 0 R
/Filter /FlateDecode
>>
stream
x��]ߏ�6~�_��qDR% �l�pY��{���-�kw�Ie[�?�툔l6@�]�(��pf��y��O�����~��{��}>|��[[�Y����/t�u߳Z�=����k�u�q����c��_~ۼ�ߵ������f:�k����?��~|���Uv�u���_�TyQm�F5u��|�c��?m��&��G���\k����2�����5�il7z�G��ֵ6�n
�}o?��
�~o��M�ը�g���t������d��a�c��p��U��&�6k�����e�W�V�zuUO^�q��Ƕ�=m^?V���ӏY?�W��S7�W�*����M;*�6{�yc����P��kihQ�G=��g�zע�M��Q�ݵT[S�I�q-U�,���ڽ��+=~�[��O�V�Z�meոŘal'������@=MK,y��P���hr�t�{�)��PO�1��dms��4���~*5"�\��+����EW����jԢ�popl�=���G�oaK[��džG�����`\Q�L��3Ӓ��<�liFQP�H>��g�e����EcF���p|���Z�(PC�{��q���F�p3U���g�z�5��]ћV�dl�T���շhu<���SL!�=�ߟf�Og���)���|�V��l5��Z��ɔg��J13��5���=g��a�Oysꉫ��lñy� ��Yѳ��Q|~�ۣ;?�<1�a�CQ�<L��<�x
�-
�m|�+J�9Oo�<;�w�8���;�����)>��,j�qo�,���Jg��i?��}�.�3G�6��3t�x�;��Nά5#�����c�Xn��M�z�n�'xn�G�\<�̝�����#�1��3�c���?a��t���b�F��(-Ss�a֚��z�`�7p�k�ar�,�8��U��i���xl��`ɌM�m��#z�&�q
Y{,�`�;�VGXlC���z���]Vn�5j������_��3^��@i!�e����˞`�:��Miɟ��Yx>���uz:V)�_ 1f�=XU\^���A�5Y�Gځ�6��,�DuNaH�[�6�C�3�x"B�K�p�On7�u���@���y ÏA8m�.���h�S O(����+����0{�]���N�X�ʹ���W��ܪ�(��T����~�\��_6�l�,�0��Ō�3}��u�t���)���ߍ�Զ��sv��ͻof��bG�U=l�zt�إ��t�R�`R�U�#0c����L��Rρ�*s��,F=g�5G����A�b��ω�Z�b������Ō�3}NZ{NZ��~N�`�bG�١���`m�'��I&1x��[��Ѽ�b�פ@��c�ֽ|X]�遀R�� �*���^f���BP�k��O�gx� ����6� ���})<V̘�R��~ ��@=Dh�G���F�ר�r�y�$x5�C�:3�B�Iw;~�ʁ�g���d������ܺ��U'�H�@QU
�Na���,`ɔ�w(�����P��Lh�k
���:�Kf��ۖҘ�Pqt� �L@�5�*C2��}?0݄��jb �����������tS�k��J�)������v-f���QbM�Πĺ���}�Qb�;z��͍k
떵P��N3xEW�=c��`�$� x��NSb(%S"�Ps��:�cl�؋�PYB�l� �*�F�9B]�=g���*�sB��#��ω�Z��9;�7���eFτN� �PB(�L�@I% �xeV��~A�a�����c���gB8Y�lB�P�D<6�zE��G�1�*�*�x�¾�D��(1��JB��P=�kE�K=7Ʉ`��.I;�#� 6+�la�MJ)��\��B��;ߒ��K
�7y��|:���&�*6����(�����qh51j���S �w
p =A!
S<�ͳsqC�M�*P����3��������t�ӵp�\2���P�Q~;��n�t0�
SDG�K��D��z�B���BZ&��C�{.��A
Y@���k$P��E;Z.���O/!{��5=���yn��߾�v
q��'�8�g?%��@�T��a�S��̈́8U�BF�g
a��݅$�>G�e}�=g��v�e�3�0����B}�=g��f�.k�0dّ�.�(�NÒ��B�����T���#K�lXY���Ō~(��~;S���m�3�i῾Ō�3}�џ+�������/�w��������yX&s%�7���7�r��,��1X��;h��Dƴ��h���')�hW4����yNO�/��v�F��'�֩Q�z�}�=g���t=WO��m�ߴ�`�bG�١�٥k}���>��H&Q��x�(�}��%�?�b�=�����0:���=p�� `���}�e$ao�)Ȉ�!`�g��Eq�.�Y�P1.8&?WGa�k@D��g�h�{#��tN�)sNq�i�(}��,�w��J"����dӁ�/����KXt���`�Q�;C)EL2.��* VM �<uI��lƞc.&[��x�Sfx� ��㵂��mcp����lx>�2���A�N ��pd�`���M1Ĺ&3t�m��t�Vg�>����I���2~a��$ab�J���)�-����@V�fH֬N$�Zu"�����c8ޯyQu�W8Y�Ř5(�
�5�
c2B)R��:�ч�9>��yj�lH=�fb�/c$ d ���I+��mQ,1�Y&����Mg�[��nsb`��{�$/!x�q�j@�ՀUf��kҀU�ڎOsҀ��|��~4`8j&ٰ����k�G �����ڣ�c+@Z�
��r#�)�n��jG+5b��d|�t<"m�:u��֓`����h�F)MN�H؉<�P W<Sc�M�O � _֚*��In- �Z[ީ�EQdjU�r��!G
3
=~#������PLg_�&�jU�Re���sZ ���u��
a;�)���\��̬��j_!:|X�7����|�{D����@T����x���M�I�)�h�����<�58��R�i�It,��m�Ҟދ��L��mY����B�C͇ Q�E�{�v�Xkd-I҄��06t&Pg�%h�!�� �kfj��i؏ht��/%���V�5�6
��[����~�dJ���Q���:1����0���}P6��h�E#
o
��?�MK�3��OP!�8��yƆu�|��i���`���'�X�N��s*�97�?`�x�2I�{uҫH���$��Q����I�=�M()C�'���Y���l��V�8���2��'�9g�&
�R^�G�{E���ka+�)Y�;�0� {u�����oB��r�[�Z��[Sp��9ps[�y��xkY�1�@٘s"%�u
���Ⱥ��J�&�����Q�#�)Ԃl��D��`ގW4P�˒=P�Oܚ�&�$~�#��E=�
��/��~$)!h̄�eSg]�������ҡ��
W�«��S�\��#5j�#Z� �ԓ���)
��s��:�5��be��$��b�R��?Ȕ� ��Z4��
� ́��P�B����
���z��Uz&Մ,8� %
U��`�sY�W(H�l;� �P<�����KϘ<�4�i�>0Ii�.0��� O�����U�u�HgL!�
������'R��@/�ܶ���Lw�ݜ�#��S�l��:�\2a�%G�g�p�
G�_A3��潢7<��� ��U�ۚl�_�F1�d���3��Mq� p�����1�6�3�v�6�ǁ��#_ ܃���d&%
a�;Aٰ����q��~�`Q�l0��s�xv�|)oR���E{_163���hmǜ1������ʌf3*PW�h,��4*�/>��d�Ft��:�/1n��k���L��(+T5�b��dd��̑�)���1�8&OQ��af*��fH� ��1�">�;%)��Snn�92~�[�UB�V�j`����S�l�Pٚ��]����$e�}��@v*wY(Ze� ��2`�P "��g@β�Pp5S��z�F�)��0�-�"ti�vo���"tY�����"t�G3;chBUu�m�qY�}�W���y<��,+$��}�'Y[�q"��+�-����\��^�|���� 7)��\բ]o�_����n$ R�����9Xn���U�Q�'�M�Fp�y�=\'�3��pԡ��F=%�ן~��[��M���/���/O?���������������I�����M�{�,�k�O�ku����0&��n�;\၀��
q�$O�q�\ � ��p5~��y�q�#�Fз�v���BLj������Jq8G��
"�s��Ô}��ϞF��xh� �d���L�c�s�^`����]���3����qP��^�;�h ��J�NL`��t��
>c>j��I���![Ʌ���J���ۅl��k���42t-[s>"��/'�b��pr�[�G;2���;�5UW)��߹�G���%�E`W�k]b�f"�sF
�"��Ա�}1v��F
)�<��0��YY�${�畑n��������}�n�)]����}�w*Gh
endstream
endobj
31 0 obj
4712
endobj
35 0 obj
[3 /XYZ 33
756.500000 0]
endobj
36 0 obj
<<
/__WKANCHOR_2 8 0 R
/__WKANCHOR_4 9 0 R
/__WKANCHOR_6 10 0 R
/__WKANCHOR_a 11 0 R
/__WKANCHOR_8 12 0 R
/__WKANCHOR_c 13 0 R
/__WKANCHOR_e 20 0 R
/__WKANCHOR_g 21 0 R
/__WKANCHOR_i 22 0 R
/__WKANCHOR_k 29 0 R
/__WKANCHOR_m 35 0 R
>>
endobj
39 0 obj
<</Title (�� P E R F O R M A N C E O F E N C O D E D F I L E S)
/Parent 38 0 R
/Dest /__WKANCHOR_4
/Count 0
/Next 40 0 R
>>
endobj
40 0 obj
<</Title (�� E N C O D E D F I L E S)
/Parent 38 0 R
/Dest /__WKANCHOR_6
/Count 0
/Next 41 0 R
/Prev 39 0 R
>>
endobj
41 0 obj
<</Title (�� L I M I T A T I O N S O F L O A D E R S A N D E N C O D E D F I L E S)
/Parent 38 0 R
/Dest /__WKANCHOR_8
/Count 0
/Next 42 0 R
/Prev 40 0 R
>>
endobj
44 0 obj
<</Title (�� \( A v a i l a b l e f o r L i n u x 3 2 a n d 6 4 b i t x 8 6 s e r v e r s u s i n g P H P 7 \))
/Parent 42 0 R
/Dest /__WKANCHOR_c
/Count 0
>>
endobj
42 0 obj
<</Title (�� I O N C U B E 2 4 : r e a l - t i m e i n t r u s i o n p r o t e c t i o n a n d P H P e r r o r r e p o r t i n g)
/Parent 38 0 R
/Dest /__WKANCHOR_a
/Count 0
/Next 43 0 R
/Prev 41 0 R
/First 44 0 R
/Last 44 0 R
>>
endobj
45 0 obj
<</Title (�� G l o b a l s e t t i n g s)
/Parent 43 0 R
/Dest /__WKANCHOR_g
/Count 0
/Next 46 0 R
>>
endobj
46 0 obj
<</Title (�� S e c u r i t y r e l a t e d s e t t i n g s)
/Parent 43 0 R
/Dest /__WKANCHOR_i
/Count 0
/Next 47 0 R
/Prev 45 0 R
>>
endobj
47 0 obj
<</Title (�� P H P E r r o r r e p o r t i n g s e t t i n g s)
/Parent 43 0 R
/Dest /__WKANCHOR_k
/Count 0
/Next 48 0 R
/Prev 46 0 R
>>
endobj
48 0 obj
<</Title (�� D e p r e c a t e d s e t t i n g s)
/Parent 43 0 R
/Dest /__WKANCHOR_m
/Count 0
/Prev 47 0 R
>>
endobj
43 0 obj
<</Title (�� p h p . i n i s e t t i n g s)
/Parent 38 0 R
/Dest /__WKANCHOR_e
/Count 0
/Prev 42 0 R
/First 45 0 R
/Last 48 0 R
>>
endobj
38 0 obj
<</Title (�� i o n C u b e L o a d e r 1 5 . 0 U s e r G u i d e)
/Parent 37 0 R
/Dest /__WKANCHOR_2
/Count 0
/First 39 0 R
/Last 43 0 R
>>
endobj
37 0 obj
<</Type /Outlines /First 38 0 R
/Last 38 0 R>>
endobj
49 0 obj
<<
/Type /Catalog
/Pages 2 0 R
/Outlines 37 0 R
/PageMode /UseOutlines
/Dests 36 0 R
>>
endobj
34 0 obj
<<
/Type /Page
/Parent 2 0 R
/Contents 50 0 R
/Resources 52 0 R
/Annots 53 0 R
/MediaBox [0 0 595 842]
>>
endobj
52 0 obj
<<
/ColorSpace <<
/PCSp 4 0 R
/CSp /DeviceRGB
/CSpg /DeviceGray
>>
/ExtGState <<
/GSa 3 0 R
>>
/Pattern <<
>>
/Font <<
/F6 6 0 R
/F7 7 0 R
>>
/XObject <<
>>
>>
endobj
53 0 obj
[ ]
endobj
50 0 obj
<<
/Length 51 0 R
/Filter /FlateDecode
>>
stream
x��\mo�6��_����$N2`�1��>i��h�f��Q�ɱd?�}V4�mD�OG玴���~dz��⎮��J���h��~�cM�"*C���z��uu��>V]�-������j?�����Z���>��ȗ��p_�i����G%��}R)����y�C����u�Rk��je�=ee-�K� [���1j�t�����
�>��IZ��Q�(LJF�(����7{�a��a��;7:[��3uV����&���ǵ*���F�'��L�^�^s'ۗE�KR{�y��S��_��P���`2�4����ϫ�+/��U�Q{��W6fm&���8�ҪS1�Xe�uT�-�KK�g���r�OqD�2��JQ�ZKr��£�'��� Aۚ���}#[� +<��O�C�Q�P5��h�{�ଓz���: ��aK\Rk�H[�����lSm�T�5�A�T�Z���,5Z�D�c�M/:�RC���`��(y�XjT�:P�3�6`�@�ź.x�(ֵl}'�aͯ����G���HO�(]w�"��
���<��xΡF�m�g0��jA��g|�O������Mm���A�o(��g�(�[�)�[G�a�o(����^<�;թ�bw�6fwℚB��vQp���B@�R��;7�pY*�=� C����_bc�{��~
{�ƾ�������6�k��6�=l�'�ƾ��JN4U�aad-8�a�c�|�:������n���߱��9�&�ȾaevWZv.:<f�x;�X�-��q��h�@��Z�D1T�z@�CN,�Ko�~4�I�!;c,�Q����5�Z��� �2w\Ӂ�~ֲJ���@R
|�A���㳻��~�����89���b��결��A���e�}�3>-� ��趇���������pj� 5�X9��Yq�gؔ�QFbn5����B+؇Q)���
����:8�O�֑
��s� ǯY>�)�q
��GG�%,?�olm�ʷ
�_0v�%:2d����g}�P�g�|�S|�U�g
�;p9��Ũ����My�7��[N��sQX��2�*�����z$��[����=��Z��KDY�
v�X�����z�Xj)�!��<
J�y��q � ��8HI�����+���-�J�N�KJ/(��J��:�@Ʃ��n�j-`�9I��A����x�{� ��c����A*� <"rRƑS�Ճg#��ǩǫ8I8������'E8k�,^�8e�U��Kj�i�����8��qϒp���OT㜣�B��Sg<�[@�~�����0n钅�8�a�n�jc��F�xs���r, V��ܨ�wV��+#jf#>�)i����'���m�1�&�7N�uC�0p����qW
� �olS���a=��}���֖'��{����BՕ����'[�qn�Gz�2-y�z����aXYg��{<��-
��sh�Q�aU?&��r*FST����|���F�wǠ�8;��r�lA6�,�MS�M������)h�sx��Z!���IKp��j�N�5�oQ�����|ˮR���-��h�#!EC�hx"�@��k����#5��?�<�0<���BkPo�ml�B?v���m�˸�0F�&��&:��RȖ��^�Nu�-y��H�C��^?�St�kq]��W#�
endstream
endobj
51 0 obj
1714
endobj
54 0 obj
<< /Type /FontDescriptor
/FontName /QCCAAA+Roboto-Regular
/Flags 4
/FontBBox [-736.816406 -270.996093 1148.43750 1056.15234 ]
/ItalicAngle 0
/Ascent 927.734375
/Descent -244.140625
/CapHeight 927.734375
/StemV 48.8281250
/FontFile2 55 0 R
>>
endobj
55 0 obj
<<
/Length1 6976
/Length 58 0 R
/Filter /FlateDecode
>>
stream
x�}X \G����{�F�1d�y0^(0@��O���nP�D.oAE�l�
Ѡ�9�$C7�j.M�L�q7�dc�i����\y_wWUW}�W��&@�!�G��Y^�[N?�#�x�f�]�u��ؾO�CWVF���q<�c>Y80v�|���e�V:8=ٍ���y���_�!�5��O�,$�d�뱯*H��8�����B[ �?
��@��.萂���]%k(.`��w���X�ZΨ�~�
�d!�f Y#o����w��pJ��!��Hm
�9"'����8B�j��S ^�j|���b�M_��8�q-�0�r�(�;j6��,����*~pPA+i��4�|�~ES���;�^G�H]��qn����a�\���u�D��28O��;;99�}&:�~�2C�⢚�> ����{�7C�+!��+
FD.�"�r����o��n��r��EƝ��g�1ᄑ��'!n���8HHjjHH�ڎM�����c�Tm ���!�3�`̿�Wc>���Lz�䋲��G��Whn�rl����2,�LT�7.v5�~���j���]��<<b�̼�T>|������Qi�z���(5HU�TqGJG�#���;��@4���к�S_57M��d\B�)3;}��G����WUL����=>ns�����7l��ag��{�-AA��EQ
�b��ˀ
7%�ݓ�V�._5�����h�9�����%�z�w���j4���2�����9*ZԵ5!I̫��{�m�L�}���#��/L<�5"�*� �S-#�ך`�~�,��� ��.��D>�(�P��~J���l@�(ԎV�(e�4�֣�h���9�-����~ْ���@��â�h�d<��~��M�B��Y������)�\����=&���� � c�U�V� ��uh��ÇY�P���}�ҹO�a7�L�P@�Noр
8"�R1^���<Q�Q)eJGn��v�_�ed��ߜ��/L��MO���������hv���������S�S�}�S9c:$�<-�ݿ�n��{��o,��b��D�9b{Kd1�j��0&�;3��Z)PQ~�����x��
DG�u�şh���n?h�B�Hi����rSfV|ז�c�ڊ�����J��u��y�3��蝹}rh7c���
cpU��@8GdR�zW��Gl���
����]�b
�n���$�b1�U�:4�U��+���3r�(+[���W�����0�v]�'���|V,�[�~�����y�z�|��K�^��� �]�?@9��َ0��R&���.g'_�IN N�|}���<T. .*�Y�T *)�`��(V0��Β�8��%��Y<he,7<��Q��{_qF��Fδ p��y 8��>hG�Ş���'��P��1��r rr?߿_X�{��Y �v�����1�3�H�&=�E7n���ǎ�����Ǟ^�©���RcG7o���3�ֱx),^�}�l����"��l���G4⠱�5�FֿUI�U#v�(�����k�B��Թ��y�2|}��͍I�ӧ ����I�0������s�%r��IӦ���n]�`eʾHL���C�ԚI�i3��$�IZ
0kf|\j��S 3�1yעn��,�Y�=5����P5���A6��^�ߊ���~��12��
?onT��O^]�E��-ҋ���B�N�w����v���&��5��w� |!�� c�oEȱ��`Z�Dw~�0n�0�c�b�˳��ǂ���}�)&�\��
��q��G����
�ե�c-�GeCf-tNzD�m��ov���[j0���a]�M�mHX����訚ٳ�%'$zz��=�܇��b�;����kz5/��`ܛ�U"w�T���S�u3�f���"�'���Y����
H���ۧ*+0xT�ݳ�X+�����i��o��L���>�6�ߧI�<�dޭs�H��ep���Wh�:l��8q��oDP���}}�<q`�9m��zt���Fzd'HzS��{�,v\A����/�U��ʗ����,<�IqgA%�Ȥ�'��p疊g�|g�p�� �'Aa��K��N�����xB܉��Kͫ6�$|�*ػW����>��~��,�`6��9�]�����K�U:0=�}����ysGyx/C�ݽ�=��\�J �[o���C�(s���}�2O"ӭ��Qi��`ͣ)�:
�%��djY髗���U���
��R�O�EG{/�V�����mQX�-� �*�\[��<��b�hL������G�A;`��R��m�$��H:wU[�V
ٽ�
�j�-v�Ҷ�����!�g�$�����{q)F�Ұ%&��Tg��>&Y�E��:��yro/��"=fNN�w�b��,~��#b���b �1�u����^��a[���{���W��:�(N���Zh�<¨�y�P<4Θ\�m��M�W���u��cclLRQDxLl��ꪜ����KQz��r�"c�3'��j������1g��>�f�s��[�� .��nȗ�Oaҝ�[���-�Y��4���ut����̿�����wMb_���0i/��1�����y��
���ZG1�;�k�6���V�d�ŀR=�$Fg��{���4S�
��87}�E���»��)�gZ�R��������cn���ҹ�fwZ�B��!�@=�i�W�!��fN+�����( �sZ5� v]��~��
��IW��ݑ� �Z�i��y�Taэ��k<�-��7����B�U�Y�v��$���ý\�ُ��s5�f,JS6|O�E�?�4 �G�*�%��qG-��9VQ�J.؆��n�>Y[ ^W{��nkX���z�\f6�٦�5k8�^DZ�H��8t%�ڱ�����A�6766��;�c4ԉV�)�Cə� `Pأ=Y��cpn��;N��W�أ�W����z0�?`>b~ӂN�g�.�b��4R�Ss�;掆Kt�q��g��<�*��k��I����eRq�D���E��~�`2m�3���ቨi"�VjIIJ��K�)t̆�;��+{v/��c���z����
�������Cq �ljlN����cZ�EX�6�b��fx�Cd#8D:6Zq�%�IaK���o�(�?�bBB�ΘX��<{&k��gc�ݖ-5��W���5nQdm��<p����?c�ښ�H�k\0G��_p:'���H�T=' /g�T1�VߢƱ��"Fi�P+����NSA�'xb��g�#��ߕJ��n�h/��{�{8ds�uX��h��YH�8�����.p�2Nng�ʀ�n�9�++7��IN���enu����O��������?O��/�R�»!�QtC��8aķ�}�|'�]Gj��\W�mKI�0}FLl����<���y�ʉ��E�?���g��ܱ�(���;W��T,���;���p�h������7ރ|��&�&���۰_̥�dZ��;�B�q�#�]��(�P��(�v���X�1G����\h��R�)}*.����k�ZJ����ls#[��S?�'z���*���}�_}����:y��4P״%*rxmH� 6mx��99��l��Ε��{"#7lţhL��&����@`H�����K�Mw[�tC�?��liP0���l
�b$�������`ş
�1�Ǵ�nL��
ow�n~8�cߥp��3�Cyܾ�V��T����5�x�~�ƣ�i���5���w��2$��c=�[��Қ�)-��>R��z�6]�"S_I� b��Y��X��X�6���7�W���mz0��q;�T�;�F�b 1���pW�3�ҥC�������l�F�*cі.ă}
��F����4b�-g��JkV1�O
�_Rw��?�(h��M�^۰ ��+^ex
*�^�(o���U�xΈ���7� h�� hAp0�]��4�+9��e<��T���kVRb�<�
[Q��CB�B��#��%�������!��<�8 ��Z� �R.���s����\9�Z���]8�����/����V�s�p�Y����0�eQ캪��N�Wߩ��ۮ�m۱#b(�q]f.�Kz!�`�������a�^ʀN�\���r$&�^A������bU�F� ���,?����@����ua����0�::2$t�����U�kbb�M^�rc��h��
^2h�;7��) �ԅ��g�g3��1������w�k8;jRbR>}��vT���
VI�l�빀6��k�/��_^�O�Z�i=?�jp/� Nc��
&�Ʋ�P)�Ãzv���HX�~6�83�k����[����:#�/��\��]��'�G�yN�����ـFϿ.�տ� J�rM=|�h��d��C9�ɾ���=�5�<�m�(�}+Q��/�k&��;���E��9�YГ
>�PM�� ������/#�|
I�/�҅W;�Hv�D�1IJ�:��䳰�AV�9�D[�Q#�C�&}���g�0�t
gH'�!�H#/=u'�d�νI�f�-9���M�\6�ϧ�[#��wH�� @_"[�e��D��?I?�����Hw��p�LEZ)8�W!^�� �z��E�q��8ѝ������"�d79K�C-����t<�E��u��ޠ"�ĵr]�~����F���0E�r��B�pE�Px({R������]�}.�;ȃ��^��6�6�6y6
67m��N�]nk��>j¨売G��j�����|�E�j���ȥG�H���l�amSD�/X���em�ؾcm���ed,̷�ǒi�߸
x��R��ڀ5u��Mq�3�6��/[�<��Y�q#w�mq��=�$@,��H
�ZRL�I&�"�D��� ��W�P|k��<���pR@��Ll�Ǒ<|�=ZU"�2��g�@c����̬R�����*�h���P���T���SűW%�������ո ��«/g\e,eO$�Iʐe'q�eyi���e0I��5�&�g�uw�m�oRFqI��@�5�Sg�g2~K��H���tQ��C��E*��L�Z�W:���f��<'G
$���H�8�#҈ǻ�$�---�5���bfZaZzV�Lcq欼���YQ�1��^3q� ��,�
endstream
endobj
58 0 obj
5242
endobj
56 0 obj
<< /Type /Font
/Subtype /CIDFontType2
/BaseFont /Roboto-Regular
/CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>
/FontDescriptor 54 0 R
/CIDToGIDMap /Identity
/W [0 [440 241 566 547 646 547 557 526 246 534 540 559 336 557 557 261 557 643 512 676 592 546 519 869 324 481 241 557 344 557 626 707 195 557 557 270 745 469 564 611 548 682 866 647 707 651 589 880 339 345 492 240 503 557 562 448 210 564 557 557 557 618 274 409 631 317 237 ]
]
>>
endobj
57 0 obj
<< /Length 826 >>
stream
/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def
/CMapName /Adobe-Identity-UCS def
/CMapType 2 def
1 begincodespacerange
<0000> <FFFF>
endcodespacerange
2 beginbfrange
<0000> <0000> <0000>
<0001> <0042> [<0069> <006F> <006E> <0043> <0075> <0062> <0065> <0020> <004C> <0061> <0064> <0072> <0031> <0035> <002E> <0030> <0055> <0073> <0047> <0054> <0068> <0063> <006D> <0074> <0076> <006C> <0070> <0066> <0067> <0050> <0048> <002C> <0032> <0034> <0049> <0077> <0079> <0045> <0052> <0046> <004F> <004D> <0041> <004E> <0044> <0053> <0057> <0028> <0029> <0078> <003A> <006B> <0033> <002B> <005F> <003B> <0071> <0037> <0038> <0036> <0042> <002D> <002F> <0056> <0022> <006A> ]
endbfrange
endcmap
CMapName currentdict /CMap defineresource pop
end
end
endstream
endobj
6 0 obj
<< /Type /Font
/Subtype /Type0
/BaseFont /Roboto-Regular
/Encoding /Identity-H
/DescendantFonts [56 0 R]
/ToUnicode 57 0 R>>
endobj
59 0 obj
<< /Type /FontDescriptor
/FontName /QHCAAA+Consolas
/Flags 4
/FontBBox [-432.128906 -302.246093 677.246093 1011.23046 ]
/ItalicAngle 0
/Ascent 742.675781
/Descent -257.324218
/CapHeight 742.675781
/StemV 70.3125000
/FontFile2 60 0 R
>>
endobj
60 0 obj
<<
/Length1 11900
/Length 63 0 R
/Filter /FlateDecode
>>
stream
x��yytǙgW7 �� � H$��M���/�% ID @�hZ�%��x��-;vd[����$���x2Il����;M6;���y��y����Yٱw=~�l�W�
�e�X�+tuu�W���jR����8�P�������`����%Vf�Ux�o������c�hde��e��X�<�L�=<�����}���u<�<�6�����ߚ(ʌ�/.��[�ڨ'(ʢ�g6^��ێ��\MQ�a�͢�(1E��(
�;�kj��
i����E-�J�7��՛@��c�R]TwS���'hZ:E�)�o���bލ2S"j��D��̀�
8EJ�7;��J��:\��`��_G0P���K���f�$��Pe�_���!frMD��*U��@p@���h����.�;�c{��~Ra�K
d�R���D)SH*�*d����5��n��g���x�mv����5FCqQ�`�r����`tnZZ�T�*�R��^�����A6{��*'CN�r��`�>��{�#�3j7��2�L&/S�f���T��j��L=���S�ĔL�R���Xƿ,3�-f�N���(�c��"�Q6����*�uא����w���4j~<��+���wN�[L�M���X���}�d:1>��b���TZgecS��PsyE�R�r9C�};�B�e��[
��8]�a��
<��90��r"�����L
���Zde���[�o��k���}��:u4�&��Rt��k�e�R��ܳR����rW�<32|y�'X+˖;]����
�r��P���ڽ���!T(��ܭk�x��n~¼���sb�
`}h�?�(��üпep���@�}�����������7���V�3�N������4*�щ�� ��W:�Ln�hW��~�ď�M!�,e1���NY(��pI6,R��I�yʍ�yvx�|��Zv����ݡ�J�ԾW���x��Z���~|�������LTӆo`i]���.~!U�9s�,�o����s�`���XOW�W�}�c���^�pT�ܾ@������Se������� n�x�;�j�[�*�]�������g6�r�F���3hd
�V�x�
b�f>O��:���
~B���yv�I�(�IN�cD����oyk�g\Nvpr���[������D|d�)d1��⨫�i�Ֆ;�Z��5ώ�AbF")�>��:��g��Ӄ[����clr����]��ju.w� �3����_�V��h*l5�kg�:MqQQ�Fge��U�+*F��H��ZQkQ�����q��Vi���7�xt��壍�G�P�:���1?'�F�<�`����(�
�+ǝ��q����o�t+����;���yi|dϤB����~���@����;=�Z�����P���j�vn�xh���.g0������PR�˟S(d�B�!�����1��])*�����`Vi
T��I���9�n�(U>恟���p�Q=�*�#�b�Q��9�/�ռxF24:>3������!�3�u�r��;w���b��^g9�H���G~z�>PQ�ӵ��/�xr_k��*�0[�
d?)hؐ�2�+RG�-(v�y�����3#���*�pEy������\�Ku~������(6Z<�mkG�.�͊f��p
��,���x�}k�7�܀=�T0/�hw(y@�k���PwV�������.?+���X��5L|5���Ţ"nJ����y����~:���k �6X��6�W)��\i���z}�~�}d��~���֦{����%�4>�Z�8R�p?{��$�L��bdU6���|fh�7/{�G�=�.W��eI���$�'��OdZ��3��$7w��Cj)������5�Ȇ��6���F���]��L ks�ɿ����ll��W[W��=911��BPf xO_s�ۣU���ᕖ��;�5�xkL�B.���{&;�+���˂��\�+)�R"��Q c�F�F��hL*��Q�u{�몽����Y��P&/Ui�&�V�Ҫ4P�X�+�5���������OT<�"�V�Y�.V(����ʚ,j�m�B���ػ�c���Xs��-���%��������Kp��r��q��Ľ��V:tZTTR�**)���A��6�����֎�S˨�.r����t���
:�����j�]Q��ZSӾg�Ζ�r�x�"j�j��hJ���W@i�q�/p��k/����p���i�$wg��w�4�ɡ3�v�Gw�T榛�~��ysm�E����]���ij@5S�O�����ןC���;�7�����o���\'�큹e�8�~�5�G��[�,��u��h����Ք�d���х�7��O�(�=��"���)��]�ʆM�_���Fy�-�^j*�L�K
eE��R�J�5؞��EQiY��t�����Qo4����G�Ӛ
v��u��>���N
����Z;B���aW�H� 4��lY;�\�Y��e�C�@
�T��e1�Kp�9�/�&8/9�z�ZL0�r�|N��rhR�ĥ���/tZ��dc]�/��{����2UyECco��t�D]����Xg��Y�Q��~֊�Ck��McuMg���`��g���}�aZ2l�v�Y͞*����5��1xȫV�E�N�$T� �6�h�p�
�!����`&X�=�����:�\NU)Bf���������3[����2}� (��.��|��OZ�u���v��jF3�1C��"\��^��(�x2\���jƶd�������:�ƈDi���hktVZ�0�hc��M�`����\e �\��ru�3���'8���4�%#��
�k�`�g�҉��v��)J3A7:
$d���^'2}-r��p�?�^G�}k��wf��K��B�S�cHI���M��Խ�zh3P�]�U'�t�[Q���v��5(WF��)�Ѩ$<�ug�}LƤ,1[�C㝡&���@Ն
��;jk�d��uLM�l<Ԥ7�45`T��
��u���D�I,�`���
G�%֘��'w��)�����q7���H$���bv���X+U�-.wm��6Y�J�i���qgW��Vo,.R��Zi0"SZf����}�m5�F�Z��c�`S(�(S�4z��+�^�5�f����Z0n�W��6{I�Q����Huj�F��i���
6-V��R�����b���#��k � x�G?"u
��\�e�|��ܴq�=���3�\�LJ����v�{���xg�������B�A�W/}㟿8�}#uS�\�M5C����`d6e9��ʅ�NU�q6 ��ñ�R5�8�SƆ`CMS������'�`��r������G�5vn�:����YWoc���ͪ�6�"��@@�PG{Q���t5���DZ({�H.s�F+[�in�ꮩ1�D}$Q�J.�JD�
���q55�h�h���6�S
_��-�'Z^5���&*,f�s�4v��1'�ߥ� =�^G��;��z@�@TK�ԣ�Co�?���5Y�k���Alt�
���P����͢�����:��l �{X!7�+��G�z�>���W?�W�f����6�5��9R�rt�X�w獡S�sTB��ǵ��:0
�������
F�NKꚚ�C�Cm�͵6�w�M���zg��\T��B�7:+��>X�hߧV�ڵk��'�M>���BB^懰+�4��x�v���o�ݻ�
�\VTl4y�[G{��n�9x|bp~�U���!}�ڵ��
�
�j8��U�ʖ��ZBc]����m]�ݽ}#��J��Q�QF�.ɈAP����}y�a��ƻ\�kFo";�.�?̈́W��_Y�~?q�CQ1He�s�P�wɝ�9!A�u�pb�G��M�b��깕/��ї�#���:���XG��B��v�N[n�V5�6�\.�f�d�]����U�@_� �ҏ<u���^=B��=#Ǐ]~��N�]�=ǎ���ag�X�[
ٹ�n��9p\�ZY3z:�q�Ve)��w���vl��Zf�%U�D
!�ڲp�Cͽ}û"F�ƀ1�頻he��_s���
��_�D:�-Vi�1�Ev[}� .�Μ��{n�aO9�/��0����>�>��Nr��&�6�:Ɲ@��O�Пq�v ���W�ז8�~���7��&+Z��!��y,�8�
�ܕW��o+�{�vÁ��3��T��x�j�@��ׇ�;۷�����P(��궎�'��R��%]W���-��.g��嬘�5l0��[#�z��ҨG��o�j�����\")+-��ڂ�*����Q�,���=�q���\^P {<mm��ݶ��@�wV���K��S�E�o�Kk���_Ҷ��tPlz�;���I��p��
%�"H�T���=��x
z�"S�$kܴش����K��k��%1�y{uwˑ��t�[�ET��<[������juW
���=�������J�\����Ѷ�J�J���\Ύ��=m�J��~��N��r�ښ�G��|���nO��vt�ȑ�dNo��U��S旦ý[�pb��O�!����ƩGT��!w�yU��GE�����k��&������b�-T��P���SO��N�S7���N�\�{�C�Tn>Ư+c�����~���'�tW�؞H|���;��ػ붆�ɂ��ߌ��>X��m�w���~���|����g��
w�W�Y��d������������������� �z ~�q��"**������/s�G#���S�!���qxW���u�́���Cm�j�^lz�,������
hU���}���~��2��"mX?�0�[��]�p�e��;���ze��o���sc�ûv�j�t�8�ؤ�������]{�����F4E�H*"\<`1�h�{���+��O��yY�߁#�'���~��)ķط�ׅ%m����v��ȳ�K��F��5���D�Ǐ�YB)�/c��^��s��
wܖD�����]�F �;���`�3p�m�p�@�愶�%h)a-�B�П��S ��C�� h^��Vh[x~��К��o�
<bd�����D����>A���oL#s��>�D�!J�>��.�'��şK�%A�i���NH�)}��t�
�>Q�O�JY�짲��Z�G~^���mE�bX1���⇊�ElQ+�n�z��۟%��멜=�B���B���ӧB_D ��S
�.�%0>%�TzW�PzP�R��q�/��'�&��W���WPy��/Bۋ� �ƒK� �F W���R�i�Oì
}������Q��@�)=r} � })u� ��C��~!���B_&�M��rj\���WP�J�ѧ�cB��J��Q߃J�j�:* �T��Pi*Ee��RY�^|��a$�$ԉ,�M%�b��06G�ûy��=��oW��c�uvG<�NeR�Y�7�^L���x*�c� vw|n>�aw�2���X��m0 �6�d&�C�0�~�����R"�۹o����:-�ͻl7N����PJ�@YxKg@6��Ja�+h��0�,Qk�X ��1�<~3�w6�y^��fG� �a�)NL��`��g�0�M����p���e��<�̥SK�x8�ZX'㱌�N��c�@�Ѵ�X�PUDh7�������/E��7���T*{7]�A>�P,���g�x���,�s��������~�҄�y�
4��^J�u��ό ���%s"D�,Y���`�B��=��]�(�������2�[�'4Ä���=�%c��>9/��b��8���Cdk,JV����V|�f5�7ssz��ě�9�7)b�X��X�0�:��bLk(#�a��(C�����=*�'ފmrX�����eBiC�Q��E�+dw�;<�_\+C�()�k(����ܕ�3A,�[=}��2M�� c1�>���#���uZ�ܻ{B�;���M_H��$��9�2y�_ ��z��
҄A� ���狷-� <�1��9�x,ː ��9��ab�$p��!F}I�)mX{KB8���;-ț\K�x��%�J+ٛ��y�[5�!���Uy��*�*)�Fn~�{zR���B�`��s��s4#؟�WΧp��lI�ov=��=8A�&�s���2#D���躟�OY�_�̟!=LPae]�9��3dn>�-�q{�/Ģ�l*�.ebl<�.�Ss���B<9�ƒ���Tr!��\NF�d�4��#K�l8�e�e�A6YH%S��p��Kf1��b,��C�&I=2N�#YȒ�|�p���Lx!�.ǣ�j6?cS�(�]Y�-��xf5�>�y�ga��T*
dR�H��3R�p�07���'c��t:�YL%��C;
��@0�$؉x2�Z��<F��Dx�
'�ex�ē��%���<V�.���f"��M��Tzv���˂�$I�q<F7)!��ԛZJ�ci� V9�,C�_H�� �B?�I����i!��X2
��NPVd"�X���Xr4�����%��I,A�n���4�Ľ��B,NdZ�|>�f��l�
D�?�������$dk0Of>��cB3 ?�5����[�,6��D*�����e����6�
g�1vf�=N�`�lО �yG[��%�<��E(�j�Z&����[����B���E���8�n�/5��.���.//�r���P���q~�6�%��C��,A�4A���9�x�lx&?��R�^��|�]ɫS��8����G��Wr���@.�1(���P,���pQRje�e�W��;���o ���ǕE����r<-���ȸYn���OU��M2�]�?�U�6�~mP�Ȅ|���#�T ��r�f��3
���%K�˕>/+_�$I~�QIy=�o�i�ߍ�k{�P
�H=|*Erp�[����� _W�g16T�� �'8��c�l{7�� �]�dq�X��G�����ш�:�BL/��0!� ����ީ$�^U��� ������w�L'` �M�#<P����i��V�]��|I�aWH�D*��)��9ň�2^j)���"vg�3K,n�Xm U-1.��%R���/BY��0`���lx)���3���;�
endstream
endobj
63 0 obj
7274
endobj
61 0 obj
<< /Type /Font
/Subtype /CIDFontType2
/BaseFont /Consolas
/CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>
/FontDescriptor 59 0 R
/CIDToGIDMap /Identity
/DW 545 >>
endobj
62 0 obj
<< /Length 742 >>
stream
/CIDInit /ProcSet findresource begin
12 dict begin
begincmap
/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def
/CMapName /Adobe-Identity-UCS def
/CMapType 2 def
1 begincodespacerange
<0000> <FFFF>
endcodespacerange
2 beginbfrange
<0000> <0000> <0000>
<0001> <0036> [<0069> <006F> <006E> <0063> <0075> <0062> <0065> <002E> <006C> <0061> <0064> <0072> <005F> <0070> <0074> <0068> <0073> <003A> <003B> <002B> <002D> <002F> <0076> <0077> <006D> <0052> <0053> <0020> <003D> <0022> <0066> <0067> <006B> <0031> <0024> <007B> <007D> <0032> <0034> <0030> <0079> <0078> <0037> <0033> <0045> <004E> <004F> <0054> <0049> <0043> <007C> <0044> <0050> <0041> ]
endbfrange
endcmap
CMapName currentdict /CMap defineresource pop
end
end
endstream
endobj
7 0 obj
<< /Type /Font
/Subtype /Type0
/BaseFont /Consolas
/Encoding /Identity-H
/DescendantFonts [61 0 R]
/ToUnicode 62 0 R>>
endobj
2 0 obj
<<
/Type /Pages
/Kids
[
5 0 R
19 0 R
28 0 R
34 0 R
]
/Count 4
/ProcSet [/PDF /Text /ImageB /ImageC]
>>
endobj
xref
0 64
0000000000 65535 f
0000000009 00000 n
0000038262 00000 n
0000000187 00000 n
0000000282 00000 n
0000000756 00000 n
0000029344 00000 n
0000038128 00000 n
0000000319 00000 n
0000000362 00000 n
0000000405 00000 n
0000000449 00000 n
0000000493 00000 n
0000000530 00000 n
0000000574 00000 n
0000001080 00000 n
0000007308 00000 n
0000000877 00000 n
0000001053 00000 n
0000007615 00000 n
0000007329 00000 n
0000007373 00000 n
0000007417 00000 n
0000007454 00000 n
0000007940 00000 n
0000012687 00000 n
0000007737 00000 n
0000007913 00000 n
0000012752 00000 n
0000012708 00000 n
0000013070 00000 n
0000017858 00000 n
0000012874 00000 n
0000013050 00000 n
0000020237 00000 n
0000017879 00000 n
0000017923 00000 n
0000020070 00000 n
0000019896 00000 n
0000018174 00000 n
0000018328 00000 n
0000018467 00000 n
0000018863 00000 n
0000019735 00000 n
0000018660 00000 n
0000019139 00000 n
0000019267 00000 n
0000019430 00000 n
0000019599 00000 n
0000020133 00000 n
0000020555 00000 n
0000022345 00000 n
0000020359 00000 n
0000020535 00000 n
0000022366 00000 n
0000022630 00000 n
0000027984 00000 n
0000028466 00000 n
0000027963 00000 n
0000029484 00000 n
0000029742 00000 n
0000037129 00000 n
0000037334 00000 n
0000037108 00000 n
trailer
<<
/Size 64
/Info 1 0 R
/Root 49 0 R
>>
startxref
38381
%%EOF
LICENCE AGREEMENT FOR THE IONCUBE PHP LOADER, PROVIDED TO ENABLE THE USE
OF IONCUBE ENCODED FILES AND AS PART OF THE IONCUBE24 SERVICE (ioncube24.com)
YOU SHOULD CAREFULLY READ THE FOLLOWING TERMS AND CONDITIONS BEFORE USING THE
LOADER SOFTWARE. THE INSTALLATION AND/OR USE OR COPYING OF THE IONCUBE PHP
LOADER SOFTWARE INDICATES YOUR ACCEPTANCE OF THIS LICENCE AGREEMENT. IF YOU
DO NOT ACCEPT THE TERMS OF THIS LICENCE AGREEMENT, DO NOT INSTALL, COPY
AND/OR USE THE LOADER SOFTWARE.
DEFINITIONS
The following definitions shall apply in this document:
LOADER shall mean the ionCube PHP Loader software package or collection
of Loaders, including any modifications or upgrades to the software, used for
executing PHP scripts previously encoded with the ionCube PHP Encoder
software to render them non-humanly readable, and any associated
documentation or electronic or online materials relating to the software.
ENCODER shall mean any ionCube PHP Encoder software or service used for the
purpose of producing non-humanly readable encoded files from PHP scripts.
ENCODED FILE shall mean a non-humanly readable file produced by the
Encoder and being derived from humanly readable PHP script source.
PROVIDER shall mean ionCube Ltd.
USER/YOU shall mean any entity who has downloaded or obtained through any
other means a version of the Loader software.
1 LICENSE ENTITLEMENT
1.1 The Loader is provided without charge. Title to the Loader does not pass
to the user in any circumstances. The Loader is supplied as object code.
1.2 The provider grants a personal, non-transferable, non-exclusive licence to
use the Loader in accordance with the terms and conditions of this Licence
Agreement.
1.3 The installation or downloading and use of the Loader entitles the user
to install and use the Loader for its own internal lawful purposes.
2 DISTRIBUTION
2.1 The Loader may be freely distributed to third parties alone or as
part of a distribution containing other items provided that this license
is also included.
2.2 The Loader may under no circumstances be branded as another product,
whether distributed or not.
2.3 Distribution as part of a commercial product is permitted provided such
distribution is in accordance with clauses 2.1 and 2.2 with respect to the
Loader.
3 ANALYSIS / REVERSE ENGINEERING / MODIFICATION
Except insofar as the user is permitted to do so in accordance with applicable
law:
3.1 Any analysis of the Loader and embedded data by any means and by
any entity whether human or otherwise and including but without limitation to
discover details of internal operation, to reverse engineer, to de-compile
object code, or to modify for the purposes of modifying behaviour is
forbidden.
3.2 Any analysis of encoded files by any means and by any entity whether human
or otherwise and including but without limitation to discover details of file
format or for the purposes of modifying behaviour or scope of their usage is
forbidden.
4 WARRANTY
THE LOADER SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
WARRANTIES INCLUDING BUT WITHOUT LIMITATION THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE ARE
DISCLAIMED. THE PROVIDER DOES NOT WARRANT THAT THE LOADER IS UNINTERRUPTED
OR ERROR FREE, NOR THAT THE OPERATION OF THE LOADER WILL FUNCTION IN
CONJUNCTION WITH ANY OTHER PRODUCT.
5 LIMITATION OF LIABILITY
5.1 IN NO EVENT WILL THE PROVIDER OF THE LOADER BE LIABLE TO THE USER OR ANY
PARTY FOR ANY DIRECT, INDIRECT, PUNITIVE, SPECIAL, INCIDENTAL OR OTHER
CONSEQUENTIAL DAMAGES ARISING DIRECTLY OR INDIRECTLY FROM THIS LICENCE
AGREEMENT OR ANY USE OF THE LOADER OR ENCODED FILES, EVEN IF THE PROVIDER IS
EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
5.2 THE LOADER IS PROVIDED ON AN "AS IS" BASIS. THE PROVIDER EXCLUDES ALL
WARRANTIES, CONDITIONS, TERMS, UNDERTAKINGS AND REPRESENTATIONS (EXCLUDING
FRAUDULENT MISREPRESENTATION) OF ANY KIND, EXPRESS OR IMPLIED, STATUTORY OR
OTHERWISE IN CONNECTION WITH THE LOADER TO THE FULLEST EXTENT PERMITTED BY
LAW.
5.3 DOWNLOADING THE LOADER IS AT YOUR OWN RISK AND THE PROVIDER DOES NOT
ACCEPT LIABILITY FOR ANY DIRECT OR INDIRECT LOSS OR DAMAGE HOWSOEVER CAUSED AS
A RESULT OF ANY COMPUTER VIRUSES, BUGS, TROJAN HORSES, WORMS, SOFTWARE BOMBS
OR OTHER SIMILAR PROGRAMS ARISING FROM YOUR USE OF THE LOADER. WHILST THE
PROVIDER WILL DO ITS BEST TO ENSURE THAT THE LOADER IS FREE FROM SUCH
DESTRUCTIVE PROGRAMS, IT IS YOUR RESPONSIBILITY TO TAKE REASONABLE PRECAUTIONS
TO SCAN FOR SUCH DESTRUCTIVE PROGRAMS DOWNLOADED FROM THE INTERNET.
5.4 THE PROVIDER'S MAXIMUM LIABILITY FOR ANY LOSS OR DAMAGE ARISING FROM THIS
LICENCE AGREEMENT SHALL IN ANY EVENT BE LIMITED IN THE SOLE DISCRETION OF THE
PROVIDER TO THE REPLACEMENT OF THE LOADER PRODUCT.
5.5 DUE TO THE NATURE OF THE INTERNET, THE PROVIDER CANNOT GUARANTEE THAT ANY
E-MAILS OR OTHER ELECTRONIC TRANSMISSIONS WILL BE SENT TO YOU OR RECEIVED BY
THE PROVIDER OR THAT THE CONTENT OF SUCH TRANSMISSIONS WILL BE SECURE DURING
TRANSMISSION.
6 BUG FIXING AND PRODUCT SUPPORT
6.1 The provider will use reasonable endeavours to provide support to users.
The provider will at their discretion only provide support for the latest
release.
6.2 Support comprises of fault reporting via tickets and fault diagnosis,
recommendations on workarounds, and where reasonably possible a timely
resolution.
6.3 The user accepts that on occasion the ability of the provider to meet
anticipated or published support schedules may be impaired due to, but without
limitation, Internet service provider failures or software failures that
affect the ability to communicate for an indeterminate period.
6.4 The provider reserves the right to refuse to provide support at any time.
6.5 The provider wishes to maintain and offer a product of the highest
possible quality, and accordingly may from time to time and at its discretion
make product changes for the purpose of correcting behaviour in variance to
the published specification or the user's reasonable expectations.
6.6 The provider reserves the right to charge for support where the user does
not have a valid support plan in place, or where the support offered exceeds
the scope of the active support plan.
7 PRODUCT UPGRADES
7.1 The provider may from time to time release product upgrades. These will
be provided free of charge and attempts made to provide a timely notification
to customers of the existence of any new release.
8 ERRORS AND OMISSIONS
Whilst reasonable endeavours are made to ensure the accuracy of documentation
concerning the details of the Loader, the user accepts the possibility of
inaccuracies in information presented in any format, including email
communications and online services. The provider shall under no circumstances
be liable for any events that arise as a result of unintentional inaccuracies
or omissions.
9 USER INDEMNITY
You agree to fully indemnify, defend and hold the provider harmless
immediately upon demand from and against all actions, liability, claims,
losses, damages, costs and expenses (including legal/attorney fees) incurred
by the provider arising directly or indirectly as a result of your breach of
this Licence Agreement.
10 INTELLECTUAL PROPERTY RIGHTS
10.1 The user acknowledges that the Loader and associated documentation and
materials contain proprietary information of the provider and are and shall
remain the exclusive property of the provider and/or its licensors and all
title, copyright, trade marks, trade names, patents and other intellectual
property rights therein of whatever nature shall remain the sole property of
the provider and/or its licensors.
10.2 No title to or rights of ownership, copyright or other intellectual
property in the Loader is transferred to the user (other than the licence
rights expressly granted in this Licence Agreement).
11 TERMINATION
11.1 The provider reserves the right to terminate this Licence Agreement
immediately by notice in writing against the user if the user is in breach of
any terms and conditions of this Licence Agreement.
11.2 Termination of this Licence Agreement for any reason shall be without
prejudice to any other rights or remedies of the provider which may have
arisen on or before the date of termination under this Licence Agreement or in
law.
11.3 The provisions of the following clauses shall survive any termination of
this agreement; clause 3, 5, 10 and 13.
12 GENERAL
12.1 The provider reserves the right to transfer or assign all or any of its
rights and duties and responsibilities set out in this Licence Agreement to
another party.
12.2 Headings have been included for convenience only and will not be used in
construing any provision of this Licence Agreement.
12.3 No delay or failure by the provider to exercise any powers, rights or
remedies under this Licence Agreement will operate as a waiver of them nor
will any single or partial exercise of any such powers, rights or remedies
include any other or further exercise of them.
12.4 If any part of this Licence Agreement is found by a court of competent
jurisdiction or other competent authority to be invalid, unlawful or
unenforceable then such part shall be severed from the remainder of this
Licence Agreement which will continue to be valid and enforceable to the
fullest extent permitted by applicable law.
12.5 This Licence Agreement including the documents or other sources referred
to herein supersede all prior representations, understandings and agreements
between the user and the provider relating to the Loader and sets forth the
entire agreement and understanding between the user and the provider relating
to the Loader.
12.6 Nothing in this Licence Agreement shall be deemed to constitute a
partnership between you and the provider nor constitute either party being an
agent of the other party.
12.7 This Agreement does not create any rights or benefits enforceable by any
person not a party to it (within the meaning of the U.K.Contracts (Rights of
Third Parties) Act 1999) except that a person who under clause 12.1 is a
permitted successor or assignee of the rights or benefits of the provider may
enforce such rights or benefits.
13 GOVERNING LAW AND JURISDICTION
This License Agreement and any issues relating thereto shall be construed and
interpreted in accordance with the laws of England and subject to the
exclusive jurisdiction of the English courts.
Copyright (c) 2002-2024 ionCube Ltd. Last revised 23-April-2015
The ionCube Loader
------------------
This package contains:
* ionCube Loaders
* a Loader Wizard script to assist with Loader installation (loader-wizard.php)
* the License document for use of the Loader and encoded files (LICENSE.txt)
* User Guide describing options that can be configured through a php.ini file.
There are options that may improve performance, particularly with files on
a network drive. Options for the ionCube24 intrusion protection and PHP error
reporting service (ioncube24.com) are also described.
INSTALLATION
============
Quick Guide for experienced system admins
-----------------------------------------
The Loader is a PHP engine extension, so should be referenced with
a zend_extension line in a php.ini file. It must be the first engine
extension to be installed.
The Loader must be for the correct operating system, match the
PHP version, and for whether PHP is built as thread-safe (TS) or not.
All information required for installing is available on a phpinfo page.
For example, if your web server is 64 bit Linux, thread safety is disabled,
PHP is version 8.1.8, the main php.ini file is /etc/php.ini and you
have unpacked Loaders to /usr/local/ioncube, you would:
1) edit /etc/php.ini
2) at the top of the php.ini file add
zend_extension = /usr/local/ioncube/ioncube_loader_lin_8.1.so
3) restart the PHP environment (i.e. Apache, php-fpm, etc.)
4) Check a phpinfo page and the Loader should show up in the Zend Engine box.
Assisted Installation with the Loader Wizard
--------------------------------------------
1. Upload the contents of this package to a directory/folder called ioncube
within the top level of your web scripts area. This is sometimes called the
"web root" or "document root". Common names for this location are "www",
"public_html", and "htdocs", but it may be different on your server.
2. Launch the Loader Wizard script in your browser. For example:
https://yourdomain/ioncube/loader-wizard.php
If the wizard is not found, check carefully the location on your server
where you uploaded the Loaders and the wizard script.
3. Follow the steps given by the Loader Wizard. If you have full access to the
server then installation should be easy. If your hosting plan is more limited,
you may need to ask your hosting provider for assistance.
4. The Loader Wizard can automatically create a ticket in our support system
if installation is unsuccessful, and we are happy to assist in that case.
YouTube with a search for "ioncube loader wizard" also gives some helpful
examples of installation.
WHERE TO INSTALL THE LOADERS
============================
The Loader Wizard should be used to guide the installation process but the
following are the standard locations for the Loader files. Loader file
packages can be obtained from https://www.ioncube.com/loaders.php
Please check that you have the correct package of Loaders for your system.
Installing to a remote SHARED server
------------------------------------
* Upload the Loader files to a directory/folder called ioncube within your
main web scripts area. (This will probably be where you placed the
loader-wizard.php script.)
Installing to a remote UNIX/LINUX DEDICATED or VPS server
---------------------------------------------------------
* Upload the Loader files to the PHP extensions directory or, if that is
not set, /usr/local/ioncube
** Installing to a remote WINDOWS DEDICATED or VPS server
* Upload the Loader files to the PHP extensions directory or, if that is
not set, C:\windows\system32
64-BIT LOADERS FOR WINDOWS
--------------------------
64-bit Loaders for Windows are available for PHP 5.5 upwards.
The Loader Wizard will not give directions for installing 64-bit Loaders for
any earlier version of PHP 5.
Copyright (c) 2002-2025 ionCube Ltd. Last revised January 2025
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.4.0
-----
* added ConsoleHandler and ConsoleFormatter which can be used to show log messages
in the console output depending on the verbosity settings
2.1.0
-----
* added ChromePhpHandler
{
"name": "symfony/monolog-bridge",
"type": "symfony-bridge",
"description": "Symfony Monolog Bridge",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3",
"monolog/monolog": "~1.3"
},
"require-dev": {
"symfony/http-kernel": "~2.2",
"symfony/console": "~2.3",
"symfony/event-dispatcher": "~2.2"
},
"suggest": {
"symfony/http-kernel": "For using the debugging handlers together with the response life cycle of the HTTP kernel.",
"symfony/console": "For the possibility to show log messages in console commands depending on verbosity settings. You need version ~2.3 of the console for it.",
"symfony/event-dispatcher": "Needed when using log messages in console commands"
},
"autoload": {
"psr-0": { "Symfony\\Bridge\\Monolog\\": "" }
},
"target-dir": "Symfony/Bridge/Monolog",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
Monolog Bridge
==============
Provides integration for Monolog with various Symfony2 components.
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Bridge/Monolog/
$ composer.phar install
$ phpunit
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.4.0
-----
* added event listeners for the session
* added the KernelEvents::FINISH_REQUEST event
2.3.0
-----
* [BC BREAK] renamed `Symfony\Component\HttpKernel\EventListener\DeprecationLoggerListener` to `Symfony\Component\HttpKernel\EventListener\ErrorsLoggerListener` and changed its constructor
* deprecated `Symfony\Component\HttpKernel\Debug\ErrorHandler`, `Symfony\Component\HttpKernel\Debug\ExceptionHandler`,
`Symfony\Component\HttpKernel\Exception\FatalErrorException`, and `Symfony\Component\HttpKernel\Exception\FlattenException`
* deprecated `Symfony\Component\HttpKernel\Kernel::init()``
* added the possibility to specify an id an extra attributes to hinclude tags
* added the collect of data if a controller is a Closure in the Request collector
* pass exceptions from the ExceptionListener to the logger using the logging context to allow for more
detailed messages
2.2.0
-----
* [BC BREAK] the path info for sub-request is now always _fragment (or whatever you configured instead of the default)
* added Symfony\Component\HttpKernel\EventListener\FragmentListener
* added Symfony\Component\HttpKernel\UriSigner
* added Symfony\Component\HttpKernel\FragmentRenderer and rendering strategies (in Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface)
* added Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel
* added ControllerReference to create reference of Controllers (used in the FragmentRenderer class)
* [BC BREAK] renamed TimeDataCollector::getTotalTime() to
TimeDataCollector::getDuration()
* updated the MemoryDataCollector to include the memory used in the
kernel.terminate event listeners
* moved the Stopwatch classes to a new component
* added TraceableControllerResolver
* added TraceableEventDispatcher (removed ContainerAwareTraceableEventDispatcher)
* added support for WinCache opcode cache in ConfigDataCollector
2.1.0
-----
* [BC BREAK] the charset is now configured via the Kernel::getCharset() method
* [BC BREAK] the current locale for the user is not stored anymore in the session
* added the HTTP method to the profiler storage
* updated all listeners to implement EventSubscriberInterface
* added TimeDataCollector
* added ContainerAwareTraceableEventDispatcher
* moved TraceableEventDispatcherInterface to the EventDispatcher component
* added RouterListener, LocaleListener, and StreamedResponseListener
* added CacheClearerInterface (and ChainCacheClearer)
* added a kernel.terminate event (via TerminableInterface and PostResponseEvent)
* added a Stopwatch class
* added WarmableInterface
* improved extensibility between bundles
* added profiler storages for Memcache(d), File-based, MongoDB, Redis
* moved Filesystem class to its own component
{
"name": "symfony/http-kernel",
"type": "library",
"description": "Symfony HttpKernel Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3",
"symfony/event-dispatcher": "~2.1",
"symfony/http-foundation": "~2.4",
"symfony/debug": "~2.3",
"psr/log": "~1.0"
},
"require-dev": {
"symfony/browser-kit": "~2.2",
"symfony/class-loader": "~2.1",
"symfony/config": "~2.0",
"symfony/console": "~2.2",
"symfony/dependency-injection": "~2.0",
"symfony/finder": "~2.0",
"symfony/process": "~2.0",
"symfony/routing": "~2.2",
"symfony/stopwatch": "~2.2",
"symfony/templating": "~2.2"
},
"suggest": {
"symfony/browser-kit": "",
"symfony/class-loader": "",
"symfony/config": "",
"symfony/console": "",
"symfony/dependency-injection": "",
"symfony/finder": ""
},
"autoload": {
"psr-0": { "Symfony\\Component\\HttpKernel\\": "" }
},
"target-dir": "Symfony/Component/HttpKernel",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
HttpKernel Component
====================
HttpKernel provides the building blocks to create flexible and fast HTTP-based
frameworks.
``HttpKernelInterface`` is the core interface of the Symfony2 full-stack
framework:
interface HttpKernelInterface
{
/**
* Handles a Request to convert it to a Response.
*
* @param Request $request A Request instance
*
* @return Response A Response instance
*/
function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
}
It takes a ``Request`` as an input and should return a ``Response`` as an
output. Using this interface makes your code compatible with all frameworks
using the Symfony2 components. And this will give you many cool features for
free.
Creating a framework based on the Symfony2 components is really easy. Here is
a very simple, but fully-featured framework based on the Symfony2 components:
$routes = new RouteCollection();
$routes->add('hello', new Route('/hello', array('_controller' =>
function (Request $request) {
return new Response(sprintf("Hello %s", $request->get('name')));
}
)));
$request = Request::createFromGlobals();
$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new RouterListener($matcher));
$resolver = new ControllerResolver();
$kernel = new HttpKernel($dispatcher, $resolver);
$kernel->handle($request)->send();
This is all you need to create a flexible framework with the Symfony2
components.
Want to add an HTTP reverse proxy and benefit from HTTP caching and Edge Side
Includes?
$kernel = new HttpKernel($dispatcher, $resolver);
$kernel = new HttpCache($kernel, new Store(__DIR__.'/cache'));
Want to functional test this small framework?
$client = new Client($kernel);
$crawler = $client->request('GET', '/hello/Fabien');
$this->assertEquals('Fabien', $crawler->filter('p > span')->text());
Want nice error pages instead of ugly PHP exceptions?
$dispatcher->addSubscriber(new ExceptionListener(function (Request $request) {
$msg = 'Something went wrong! ('.$request->get('exception')->getMessage().')';
return new Response($msg, 500);
}));
And that's why the simple looking ``HttpKernelInterface`` is so powerful. It
gives you access to a lot of cool features, ready to be used out of the box,
with no efforts.
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/HttpKernel/
$ composer.phar install
$ phpunit
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.1.0
-----
* added TraceableEventDispatcherInterface
* added ContainerAwareEventDispatcher
* added a reference to the EventDispatcher on the Event
* added a reference to the Event name on the event
* added fluid interface to the dispatch() method which now returns the Event
object
* added GenericEvent event class
* added the possibility for subscribers to subscribe several times for the
same event
* added ImmutableEventDispatcher
{
"name": "symfony/event-dispatcher",
"type": "library",
"description": "Symfony EventDispatcher Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/dependency-injection": "~2.0"
},
"suggest": {
"symfony/dependency-injection": "",
"symfony/http-kernel": ""
},
"autoload": {
"psr-0": { "Symfony\\Component\\EventDispatcher\\": "" }
},
"target-dir": "Symfony/Component/EventDispatcher",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
EventDispatcher Component
=========================
The Symfony2 EventDispatcher component implements the Mediator pattern in a
simple and effective way to make your projects truly extensible.
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
$dispatcher = new EventDispatcher();
$dispatcher->addListener('event_name', function (Event $event) {
// ...
});
$dispatcher->dispatch('event_name');
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/EventDispatcher/
$ composer.phar install
$ phpunit
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.3.0
-----
* added classes to make operations on catalogues (like making a diff or a merge on 2 catalogues)
* added Translator::getFallbackLocales()
* deprecated Translator::setFallbackLocale() in favor of the new Translator::setFallbackLocales() method
2.2.0
-----
* QtTranslationsLoader class renamed to QtFileLoader. QtTranslationsLoader is deprecated and will be removed in 2.3.
* [BC BREAK] uniformized the exception thrown by the load() method when an error occurs. The load() method now
throws Symfony\Component\Translation\Exception\NotFoundResourceException when a resource cannot be found
and Symfony\Component\Translation\Exception\InvalidResourceException when a resource is invalid.
* changed the exception class thrown by some load() methods from \RuntimeException to \InvalidArgumentException
(IcuDatFileLoader, IcuResFileLoader and QtFileLoader)
2.1.0
-----
* added support for more than one fallback locale
* added support for extracting translation messages from templates (Twig and PHP)
* added dumpers for translation catalogs
* added support for QT, gettext, and ResourceBundles
{
"name": "symfony/translation",
"type": "library",
"description": "Symfony Translation Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/config": "~2.0",
"symfony/yaml": "~2.2"
},
"suggest": {
"symfony/config": "",
"symfony/yaml": ""
},
"autoload": {
"psr-0": { "Symfony\\Component\\Translation\\": "" }
},
"target-dir": "Symfony/Component/Translation",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
Translation Component
=====================
Translation provides tools for loading translation files and generating
translated strings from these including support for pluralization.
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Loader\ArrayLoader;
$translator = new Translator('fr_FR', new MessageSelector());
$translator->setFallbackLocales(array('fr'));
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', array(
'Hello World!' => 'Bonjour',
), 'fr');
echo $translator->trans('Hello World!')."\n";
Resources
---------
Silex integration:
https://github.com/fabpot/Silex/blob/master/src/Silex/Provider/TranslationServiceProvider.php
Documentation:
http://symfony.com/doc/2.4/book/translation.html
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/Translation/
$ composer.phar install
$ phpunit
Copyright (c) 1997-2017, Chuck Hagenbuch
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.1.0
-----
* added Locale::getIntlIcuVersion(), Locale::getIntlIcuDataVersion(), Locale::getIcuDataVersion() and Locale::getIcuDataDirectory()
* renamed update-data.php to build-data.php, the script usage changed, now it is easier to update the ICU data
* updated the ICU data to the release 49.1.2
{
"name": "symfony/locale",
"type": "library",
"description": "Symfony Locale Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3",
"symfony/intl": ">=2.3"
},
"autoload": {
"psr-0": { "Symfony\\Component\\Locale\\": "" }
},
"target-dir": "Symfony/Component/Locale",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
Locale Component
================
Locale provides fallback code to handle cases when the ``intl`` extension is
missing.
The Locale component is deprecated since version 2.3 and will be removed in
Symfony 3.0. You should use the more capable Intl component instead.
CREDITS
=======
eZ Components team
------------------
- Sergey Alexeev
- Sebastian Bergmann
- Jan Borsodi
- Raymond Bosman
- Frederik Holljen
- Kore Nordmann
- Derick Rethans
- Vadym Savchuk
- Tobias Schlitt
- Alexandru Stanoi
eZ Components Licence
=====================
New BSD Licence
---------------
Copyright (c) 2005-2008, eZ Systems A.S.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of eZ Systems A.S. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<?php
require_once 'tutorial_autoload.php';
$options = new ezcArchiveOptions( array( 'readOnly' => true ) );
$archive = ezcArchive::open(
"compress.zlib:///tmp/my_archive.tar.gz", null, $options );
// The foreach method calls internally the iterator methods.
foreach( $archive as $entry )
{
echo $entry, "\n";
$archive->extractCurrent( "/tmp/target_location/" );
}
?>
<?php
require_once 'tutorial_autoload.php';
date_default_timezone_set( "UTC" );
// Open the gzipped TAR archive.
$archive = ezcArchive::open( "compress.zlib:///tmp/my_archive.tar.gz" );
while( $archive->valid() )
{
// Returns the current entry (ezcArchiveEntry).
$entry = $archive->current();
// ezcArchiveEntry has an __toString() method.
echo $entry, "\n";
// Extract the current archive entry to /tmp/target_location/
$archive->extractCurrent( "/tmp/target_location/" );
$archive->next();
}
?>
<?php
require_once 'tutorial_autoload.php';
date_default_timezone_set( "UTC" );
$archive = ezcArchive::open( "/tmp/my_archive.zip" );
$archive->truncate();
$filesToAppend[] = "/tmp/directory/";
$filesToAppend[] = "/tmp/file.txt";
// The second parameter specifies prefix. The prefix is normally not included
// in the archive.
$archive->appendToCurrent( $filesToAppend, "/tmp/" );
?>
<?php
$dir = dirname( __FILE__ );
$dirParts = explode( DIRECTORY_SEPARATOR, $dir );
switch ( $dirParts[count( $dirParts ) - 3] )
{
case 'doc': require_once 'ezc/Base/base.php'; break; // pear
case 'trunk': require_once "$dir/../../Base/src/base.php"; break; // svn
default: require_once "$dir/../../Base/src/base.php"; break; // bundle
}
/**
* Autoload ezc classes
*
* @param string $className
*/
function __autoload( $className )
{
ezcBase::autoload( $className );
}
?>
<?php
require_once 'tutorial_autoload.php';
$archive = ezcArchive::open( "compress.zlib:///tmp/my_archive.tar.gz" );
// The foreach method calls internally the iterator methods.
foreach( $archive as $entry )
{
echo $entry, "\n";
$archive->extractCurrent( "/tmp/target_location/" );
}
?>
eZ Components - Archive
~~~~~~~~~~~~~~~~~~~~~~~
.. contents:: Table of Contents
Introduction
============
The Archive component provides a generic API for creating and extracting
archives. Currently, the Archive component supports the Tar and Zip formats.
Compression algorithms, such as GZip or BZip2, are indirectly supported.
The stream wrappers from PHP should be used to handle compressed archives.
Class overview
==============
The following list sums up the most important classes:
ezcArchive
This class provides the main API for accessing or creating a
Tar or Zip archive. ezcArchive provides methods for
extracting entries (files, directories, symbolic links and so on), appending
entries and removing entries.
ezcArchiveEntry
The ezcArchiveEntry class is returned when an entry (such as a file or
directory) is requested from the opened archive. ezcArchiveEntry provides
entry information about the path, its access rights and whether the entry is
a directory, a symbolic link, a hard link, a block-file and so on. The owner name, the
group name and the last access time are also available.
More information about these classes can be found in the documentation of the
class itself.
Usage
=====
The following examples demonstrate how to use the Archive component.
Extracting a Tar-archive
------------------------
The Tar format has more than one standard. The most common formats are:
- Gnu
- POSIX
- Unix V7
- Ustar (The default when creating a tar archive)
The Archive component can extract from any of these formats. Appending entries
to the archive is only available for the Unix V7 and Ustar formats.
Extracting entries can occur in two ways:
- ezcArchive->extract(), extracts all entries from the archive.
- ezcArchive->extractCurrent(), extracts only the current entry.
An ezcArchive object can be used like an iterator. After opening the file, it
points to the first entry. The iterator can be moved using ezcArchive->next()
and ezcArchive->rewind() to move to the next entry or go back to the first
entry.
The next example demonstrates how to extract an entire archive file-by-file:
.. include:: tutorial_extract.php
:literal:
First, tutorial_autoload.php is included. The included file loads the
correct php files for the Archive package. Hereafter the time zone is set to
"UTC". The Archive component uses some date functions and might therefore
produce warnings if the time zone is not specified.
The gzipped Tar archive is opened using the zlib stream. The while() method
iterates over each entry, showing the name and extracting the entry itself.
The Archive component extends from the PHP Iterator class, thus the above
example can be rewritten as follows:
.. include:: tutorial_iterator.php
:literal:
Please be aware that by default archive files are opened in read/write mode. In
order to prevent that, you can set an option to open the archive in read-only
mode. This also prevents the modify and create timestamps of the file to be
preserved. The following example shows that:
.. include:: tutorial_read_only.php
:literal:
Appending files to an archive
-----------------------------
Unfortunately, it is not yet possible to directly append files to a gzipped or
bzipped Tar archive. The ZLib and BZip2 libraries do not support opening a file
for reading and writing.
ezcArchive has two methods for appending files:
- ezcArchive->append(), appends entries to the end of the archive.
- ezcArchive->appendCurrent(), appends entries after the current entry and
removes the rest of the files from the archive.
To replace the first file as well, use ezcArchive->truncate(). The
next example replaces all entries from an existing Zip archive with the files
file1.txt and file2.txt:
.. include:: tutorial_replacing.php
:literal:
Appending directories to an archive
-----------------------------------
You need to append a slash '/' to the end of the directory name that is added
to an archive.
The next example replaces all entries from an existing Zip archive with the
'directory' folder and the 'file.txt' file:
.. include:: tutorial_directories.php
:literal:
Appending a directory tree to an archive
----------------------------------------
Using the function ezcBase::walkRecursive() a directory tree can be added to
an archive.
The next example shows how to browse a directory tree and add all the files
and directories inside to an archive:
.. include:: tutorial_recursive.php
:literal:
The **ArchiveContext** class will hold the archive object which is passed to
the callback function *findRecursiveCallback*. The *appendRecursive* function
sets up the context object (of class **ArchiveContext**) and calls the
*findRecursiveCallback* function. In the *findRecursiveCallback* function the
current file or directory is appended to the archive object inside the
context.
More Information
================
For more information, see the ezcArchive API documentation.
..
Local Variables:
mode: rst
fill-column: 79
End:
vim: et syn=rst tw=79
<?php
require_once 'tutorial_autoload.php';
date_default_timezone_set( "UTC" );
$archive = ezcArchive::open( "/tmp/my_archive.zip" );
$archive->truncate();
$filesToAppend[] = "/tmp/file1.txt";
$filesToAppend[] = "/tmp/file2.txt";
// The second parameter specifies prefix. The prefix is normally not included
// in the archive.
$archive->appendToCurrent( $filesToAppend, "/tmp/" );
?>
<?php
/**
* @package Archive
*/
// Add "MyDirectory" to a new archive: myArchive.tar
// [ tar -cf myArchive.tar MyDirectory ]
$ar = new Tar( "myArchive.tar" );
$ar->append( "MyDirectory" );
// Show the files in the archive.
// [ tar -tf myArchive.tar ]
$fileListing = $ar->getList();
foreach( $fileListing as $file )
{
print( "Archived file: $file\n" );
}
// Append the file /etc/passwd
// [ tar -rf myArchive.tar /etc/passwd ]
$ar->append( "/etc/passwd" );
// Delete the directory and it's contents
// [ tar -f myArchive.tar --delete MyDirectory ]
$ar->delete( "MyDirectory" );
// Append another directory ..
$ar->append( "AnotherDirectory" );
// .. and show detailed file permissions plus the file or directory path.
$fileListing = $ar->getList();
foreach( $fileListing as $file )
{
$entry = $ar->getArchivedEntry( $file );
print( $entry->getPermissionsString() );
if ( $entry->isDirectory() )
{
print( " [ ".$entry->getPath()." ]\n" );
}
else
{
print( " ".$entry->getPath()."\n" );
}
}
// Extract the whole archive to the tmp directory
$ar->extractTo( "/tmp/" );
// Extract the passwd file to the file: /tmp/passwd-backup
$ar->extractTo( "/tmp/passwd-backup", "passwd" );
// Extracting the gzipped archive: compressedTar.tgz to the tmp directory:
$ar = new Tar( "compress.zlib://compressedTar.tgz" );
$ar->extractTo( "/tmp/" );
// .. and append the password file.
$ar->append( "/etc/passwd" );
?>
<?php
require_once 'tutorial_autoload.php';
date_default_timezone_set( "UTC" );
class ArchiveContext extends ezcBaseFileFindContext
{
public $archive;
public $prefix;
}
function findRecursiveCallback( ezcBaseFileFindContext $context, $sourceDir, $fileName, $fileInfo )
{
$path = "{$sourceDir}/{$fileName}";
if ( is_dir( $path ) )
{
$path .= '/';
}
$context->archive->append( array( $path ), $context->prefix );
}
function appendRecursive( $archive, $sourceDir, $prefix )
{
$context = new ArchiveContext();
$context->archive = $archive;
$context->prefix = $prefix;
ezcBaseFile::walkRecursive( $sourceDir, array(), array(), 'findRecursiveCallback', $context );
}
$archive = ezcArchive::open( "my_archive.zip", ezcArchive::ZIP );
$archive->truncate();
// the 2nd parameter is the directory, the 3rd parameter is the prefix
appendRecursive( $archive, '/tmp/directory/', '/tmp/directory/' );
?>
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.4.0
-----
* deprecated the DebugClassLoader as it has been moved to the Debug component instead
2.3.0
-----
* added a WinCacheClassLoader for WinCache
2.1.0
-----
* added a DebugClassLoader able to wrap any autoloader providing a findFile
method
* added a new ApcClassLoader and XcacheClassLoader using composition to wrap
other loaders
* added a new ClassLoader which does not distinguish between namespaced and
pear-like classes (as the PEAR convention is a subset of PSR-0) and
supports using Composer's namespace maps
* added a class map generator
* added support for loading globally-installed PEAR packages
{
"name": "symfony/class-loader",
"type": "library",
"description": "Symfony ClassLoader Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"minimum-stability": "dev",
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/finder": "~2.0"
},
"autoload": {
"psr-0": { "Symfony\\Component\\ClassLoader\\": "" }
},
"target-dir": "Symfony/Component/ClassLoader",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
ClassLoader Component
=====================
ClassLoader loads your project classes automatically if they follow some
standard PHP conventions.
The Universal ClassLoader is able to autoload classes that implement the PSR-0
standard or the PEAR naming convention.
First, register the autoloader:
require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
use Symfony\Component\ClassLoader\UniversalClassLoader;
$loader = new UniversalClassLoader();
$loader->register();
Then, register some namespaces with the `registerNamespace()` method:
$loader->registerNamespace('Symfony', __DIR__.'/src');
$loader->registerNamespace('Monolog', __DIR__.'/vendor/monolog/src');
The `registerNamespace()` method takes a namespace prefix and a path where to
look for the classes as arguments.
You can also register a sub-namespaces:
$loader->registerNamespace('Doctrine\\Common', __DIR__.'/vendor/doctrine-common/lib');
The order of registration is significant and the first registered namespace
takes precedence over later registered one.
You can also register more than one path for a given namespace:
$loader->registerNamespace('Symfony', array(__DIR__.'/src', __DIR__.'/symfony/src'));
Alternatively, you can use the `registerNamespaces()` method to register more
than one namespace at once:
$loader->registerNamespaces(array(
'Symfony' => array(__DIR__.'/src', __DIR__.'/symfony/src'),
'Doctrine\\Common' => __DIR__.'/vendor/doctrine-common/lib',
'Doctrine' => __DIR__.'/vendor/doctrine/lib',
'Monolog' => __DIR__.'/vendor/monolog/src',
));
For better performance, you can use the APC based version of the universal
class loader:
require_once __DIR__.'/src/Symfony/Component/ClassLoader/UniversalClassLoader.php';
require_once __DIR__.'/src/Symfony/Component/ClassLoader/ApcUniversalClassLoader.php';
use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
$loader = new ApcUniversalClassLoader('apc.prefix.');
Furthermore, the component provides tools to aggregate classes into a single
file, which is especially useful to improve performance on servers that do not
provide byte caches.
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/ClassLoader/
$ composer.phar install
$ phpunit
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.4.0
-----
* added support for expressions in service definitions
* added ContainerAwareTrait to add default container aware behavior to a class
2.2.0
-----
* added Extension::isConfigEnabled() to ease working with enableable configurations
* added an Extension base class with sensible defaults to be used in conjunction
with the Config component.
* added PrependExtensionInterface (to be able to allow extensions to prepend
application configuration settings for any Bundle)
2.1.0
-----
* added IntrospectableContainerInterface (to be able to check if a service
has been initialized or not)
* added ConfigurationExtensionInterface
* added Definition::clearTag()
* component exceptions that inherit base SPL classes are now used exclusively
(this includes dumped containers)
* [BC BREAK] fixed unescaping of class arguments, method
ParameterBag::unescapeValue() was made public
{
"name": "symfony/dependency-injection",
"type": "library",
"description": "Symfony DependencyInjection Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/yaml": "~2.0",
"symfony/config": "~2.2",
"symfony/expression-language": "~2.4"
},
"suggest": {
"symfony/yaml": "",
"symfony/config": "",
"symfony/proxy-manager-bridge": "Generate service proxies to lazy load them"
},
"autoload": {
"psr-0": { "Symfony\\Component\\DependencyInjection\\": "" }
},
"target-dir": "Symfony/Component/DependencyInjection",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
DependencyInjection Component
=============================
DependencyInjection manages your services via a robust and flexible Dependency
Injection Container.
Here is a simple example that shows how to register services and parameters:
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
$sc = new ContainerBuilder();
$sc
->register('foo', '%foo.class%')
->addArgument(new Reference('bar'))
;
$sc->setParameter('foo.class', 'Foo');
$sc->get('foo');
Method Calls (Setter Injection):
$sc = new ContainerBuilder();
$sc
->register('bar', '%bar.class%')
->addMethodCall('setFoo', array(new Reference('foo')))
;
$sc->setParameter('bar.class', 'Bar');
$sc->get('bar');
Factory Class:
If your service is retrieved by calling a static method:
$sc = new ContainerBuilder();
$sc
->register('bar', '%bar.class%')
->setFactoryClass('%bar.class%')
->setFactoryMethod('getInstance')
->addArgument('Aarrg!!!')
;
$sc->setParameter('bar.class', 'Bar');
$sc->get('bar');
File Include:
For some services, especially those that are difficult or impossible to
autoload, you may need the container to include a file before
instantiating your class.
$sc = new ContainerBuilder();
$sc
->register('bar', '%bar.class%')
->setFile('/path/to/file')
->addArgument('Aarrg!!!')
;
$sc->setParameter('bar.class', 'Bar');
$sc->get('bar');
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/DependencyInjection/
$ composer.phar install
$ phpunit
CREDITS
=======
eZ Components team
------------------
- Sergey Alexeev
- Sebastian Bergmann
- Jan Borsodi
- Raymond Bosman
- Frederik Holljen
- Kore Nordmann
- Derick Rethans
- Vadym Savchuk
- Tobias Schlitt
- Alexandru Stanoi
eZ Components Licence
=====================
New BSD Licence
---------------
Copyright (c) 2005-2008, eZ Systems A.S.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of eZ Systems A.S. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<?php
require 'tutorial_autoload.php';
$data = ezcBaseFile::findRecursive(
"/dat/dev/ezcomponents",
array( '@src/.*_autoload.php$@' ),
array( '@/autoload/@' )
);
var_dump( $data );
?>
<?php
require 'tutorial_autoload.php';
ezcBaseFile::removeRecursive( '/dat/dev/ezcomponents/trash' );
?>
<?php
$dir = dirname( __FILE__ );
$dirParts = explode( DIRECTORY_SEPARATOR, $dir );
switch ( $dirParts[count( $dirParts ) - 3] )
{
case 'doc': require_once 'ezc/Base/base.php'; break; // pear
case 'trunk': require_once "$dir/../../Base/src/base.php"; break; // svn
default: require_once "$dir/../../Base/src/base.php"; break; // bundle
}
/**
* Autoload ezc classes
*
* @param string $className
*/
function __autoload( $className )
{
ezcBase::autoload( $className );
}
?>
<?php
require 'tutorial_autoload.php';
class myProgressFinder
{
static public function findRecursiveCallback( ezcBaseFileFindContext $context, $sourceDir, $fileName, $fileInfo )
{
// ignore if we have a directory, but do print a "." and sleep for
// extra demo time
if ( $fileInfo['mode'] & 0x4000 )
{
echo ".";
usleep( 100000 );
return;
}
// update the statistics
$context->elements[] = $sourceDir . DIRECTORY_SEPARATOR . $fileName;
$context->count++;
$context->size += $fileInfo['size'];
}
static public function findRecursive( $sourceDir, array $includeFilters = array(), array $excludeFilters = array() )
{
// create the context, and then start walking over the array
$context = new ezcBaseFileFindContext;
ezcBaseFile::walkRecursive( $sourceDir, $includeFilters, $excludeFilters,
array( 'myProgressFinder', 'findRecursiveCallback' ), $context );
// collect the statistics (which we don't do anything with in this example)
$statistics['size'] = $context->size;
$statistics['count'] = $context->count;
// return the found and pattern-matched files
sort( $context->elements );
return $context->elements;
}
}
$files = myProgressFinder::findRecursive( dirname( __FILE__ ) );
var_dump( $files );
?>
<?php
class erMyClass1
{
function toString()
{
echo "Class 'erMyClass1'\n";
}
}
?><?php
class erMyClass2
{
function toString()
{
echo "Class 'erMyClass2'\n";
}
}
?><?php
class erYourClass1
{
function toString()
{
echo "Class 'erYourClass1'\n";
}
}
?><?php
class erYourClass2
{
function toString()
{
echo "Class 'erYourClass2'\n";
}
}
?><?php
return array (
'erYourClass1' => 'You/yourclass1.php',
'erYourClass2' => 'You/yourclass2.php',
);
?>
<?php
return array (
'erMyClass1' => 'Me/myclass1.php',
'erMyClass2' => 'Me/myclass2.php',
);
?>
eZ Components - Base
~~~~~~~~~~~~~~~~~~~~
.. contents:: Table of Contents
Introduction
============
The Base component provides the basic functionality, such as autoloading, that
all eZ Components need to function properly. The Base component needs to be
loaded specifically. Base can also autoload external class repositories from
outside the eZ Components.
Aside from the autoload functionality, the Base component also contains a number of
generic Exception classes that all inherit from the ezcBaseException class.
Installation
============
The installation and configuration of the eZ Components environment is
described in a separate article. Please refer to the `Components Introduction`_
for instructions on installation and configuration of the eZ Components library
and the Base component.
.. _Components Introduction: /docs/install
Usage
=====
Debugging
---------
By default the ezcBase component's autoload mechanism will not throw an
exception when an autoload class can not be found. In some cases (during
development) it is useful to have an exception with detailed information
about which autoload files were searched for, and in which directories.
ezcBase supports an option that enables this behavior::
<?php
$options = new ezcBaseAutoloadOptions;
$options->debug = true;
ezcBase::setOptions( $options );
?>
**Warning**: Exceptions are ignored when they are thrown from an autoload()
handler in PHP. In order to see the exception message that is thrown when a
class can not be found, you need to catch the exception *in* the autoload()
handler. Your autoload() function could then look like::
function __autoload( $className )
{
try
{
ezcBase::autoload( $className );
}
catch ( Exception $e )
{
echo $e->getMessage();
}
}
Preloading
----------
The default autoload policy of the eZ Components is to load every class
file on demand only. It is also possible to load all classes of one
component at the same time, when one of the component's classes is
requested for the first time. You can change this behavior with the
"preload" option that is available through the ezcBaseAutoloadOptions option
class. You can turn preloading on with::
<?php
$options = new ezcBaseAutoloadOptions;
$options->preload = true;
ezcBase::setOptions( $options );
?>
Please note that preloading will *not* be done for Exception classes.
Adding class repositories located outside eZ Components to autoload system
--------------------------------------------------------------------------
It can be useful to add repositories of user-defined classes to the eZ
Components autoload system. The ezcBase::addClassRepository() method can be
used to perform this task. You need to arrange the desired external classes
in a class repository. That is, make sure that classes and corresponding
\*_autoload.php files are named and placed according to the explanations below.
After they are in the proper structure, you can call addClassRepository() with
the proper parameters before you use the external classes.
External classes will then be loaded by autoload system.
ezcBase::addClassRepository() takes two arguments:
- $basePath is the base path for the whole class repository.
- $autoloadDirPath is the path where autoload files for this repository are found.
The paths in the autoload files are *not* relative to the package directory
as specified by the $basePath argument. In other words, class definition files will
only be searched for in the location $autoloadDirPath.
Consider the following example:
- There is a class repository stored in the directory "./repos".
- Autoload files for this repository are stored in "./repos/autoloads".
- There are two components in this repository: "Me" and "You".
- The "Me" component has the classes "erMyClass1" and "erMyClass2".
- The "You" component has the classes "erYourClass1" and "erYourClass2".
In this case, you need to create the following files in "./repos/autoloads".
Note that the prefix to _autoload.php ("my" and "your") in the filename is the
first part of the classname (excluding the lowercase classname prefix - "er").
Content of my_autoload.php:
.. include:: repos/autoloads/my_autoload.php
:literal:
Content of your_autoload.php:
.. include:: repos/autoloads/your_autoload.php
:literal:
The directory structure for the external repository is then: ::
./repos/autoloads/my_autoload.php
./repos/autoloads/your_autoload.php
./repos/Me/myclass1.php
./repos/Me/myclass2.php
./repos/You/yourclass1.php
./repos/You/yourclass2.php
To use this repository with the autoload mechanism, use the
following code:
.. include:: tutorial_example_01.php
:literal:
The above code will output: ::
Class 'erMyClass2'
Class 'erYourClass1'
Lazy initialization
-------------------
Lazy initialization is a mechanism to load and configure a component, only
when it is really used in your application. This mechanism saves time for
parsing the classes and configuration, when the component is not used at all
during one request. The implementation in ezcBaseInit may be reused by other
applications and components, like the following example will show.
.. include:: tutorial_lazy_initialization.php
:literal:
The example shows a random class implementing the singleton pattern, which may
be some database connection handler, or anything similar in your case. The
getInstance() method shows a typical PHP 5 implementation except the
additional line 14, which checks, if a configuration callback was provided
earlier and configures the newly created instance. If no configuration
callback was provided, nothing will happen. The customKey is used to receive
the right callback from ezcBaseInit and needs to be known by the user, who
wants to define a configuration callback for your class.
In line 32 the class used to configure your instance on creation is defined.
The first parameter is the key used earlier in the getInstance method, to
reference the right class, and the second parameter is the name of your
configuration class.
The configuration class beginning in line 22 just needs to implement the
ezcBaseConfigurationInitializer interface, which defines one
method: configureObject(). This method will be called with the object to
configure as a single parameter. In the example, a new public property on the
customSingleton instance is created, which will be echo'd later to show the
success of the configuration.
The configuration itself will not happen before the actual instance is created
in line 35 performing the static call on customSingleton::getInstance(). The
var_dump() in the following line shows, that the property value is set and
contains the earlier set value (int) 42.
File Operations
---------------
Finding files recursively
`````````````````````````
This example shows how to use the ezcBaseFile::findRecursive() method:
.. include:: tutorial_example_02.php
:literal:
The code in this example searches for files in the ``/dat/dev/ezcomponents``
directory. It will only include files that match *all* patterns in the
$includeFilters array (the second parameter). Files that match *any* of the
patterns in the $excludeFilters array (the third parameter) will not be returned.
In other words, the code above searches for files in the ``dat/dev/ezcomponents``
directory, which are in the ``src/`` directory and end with ``_autoload.php``,
except for files that are in the ``/autoload/`` directory.
Removing directories recursively
````````````````````````````````
This example shows how to use the ezcBaseFile::removeRecursive() method:
.. include:: tutorial_example_03.php
:literal:
This code simply removes the directory ``/dat/dev/ezcomponents/trash`` and all
of its files and sub-directories.
**Warning: Use this function with care, as it has the potential to erase
everything that the current user has access to.**
Overloading the callback
````````````````````````
The ezcBaseFile::findRecursive() method internally uses the
ezcBaseFile::walkRecursive() method to do the actual recursing. The callback
method ezcBaseFile::findRecursiveCallback() is then responsible for collecting
the data. In case you want to do additional things, such as printing progress,
you can either call walkRecursive() yourself with a callback function of your
choice, or overload the ezcBaseFile class and provide a new
findRecursiveCallback() method. The code below uses
ezcBaseFile::walkRecursive() directly in order to display dots for when ever it
finds a new directory:
.. include:: tutorial_example_04.php
:literal:
..
Local Variables:
mode: rst
fill-column: 79
End:
vim: et syn=rst tw=79
<?php
require_once 'tutorial_autoload.php';
// Create a custom class implementing the singleton pattern
class customSingleton
{
protected static $instance;
public static function getInstance()
{
if ( self::$instance === null )
{
self::$instance = new customSingleton();
ezcBaseInit::fetchConfig( 'customKey', self::$instance );
}
return self::$instance;
}
}
// Implement your configuration class
class customSingletonConfiguration implements ezcBaseConfigurationInitializer
{
public static function configureObject( $object )
{
echo "Configure customSingleton.\n";
$object->value = 42;
}
}
// Register for lazy initilization
ezcBaseInit::setCallback( 'customKey', 'customSingletonConfiguration' );
// Configure on first initilization
$object = customSingleton::getInstance();
var_dump( $object->value );
?>
<?php
require_once 'tutorial_autoload.php';
ezcBase::addClassRepository( './repos', './repos/autoloads' );
$myVar1 = new erMyClass2();
$myVar1->toString();
$yourVar1 = new erYourClass1();
$yourVar1->toString();
?>
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.4.0
-----
* `Crawler::addXmlContent()` removes the default document namespace again if it's an only namespace.
* added support for automatic discovery and explicit registration of document
namespaces for `Crawler::filterXPath()` and `Crawler::filter()`
* improved content type guessing in `Crawler::addContent()`
* [BC BREAK] `Crawler::addXmlContent()` no longer removes the default document
namespace
2.3.0
-----
* added Crawler::html()
* [BC BREAK] Crawler::each() and Crawler::reduce() now return Crawler instances instead of DomElement instances
* added schema relative URL support to links
* added support for HTML5 'form' attribute
2.2.0
-----
* added a way to set raw path to the file in FileFormField - necessary for
simulating HTTP requests
2.1.0
-----
* added support for the HTTP PATCH method
* refactored the Form class internals to support multi-dimensional fields
(the public API is backward compatible)
* added a way to get parsing errors for Crawler::addHtmlContent() and
Crawler::addXmlContent() via libxml functions
* added support for submitting a form without a submit button
{
"name": "symfony/dom-crawler",
"type": "library",
"description": "Symfony DomCrawler Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/css-selector": "~2.0"
},
"suggest": {
"symfony/css-selector": ""
},
"autoload": {
"psr-0": { "Symfony\\Component\\DomCrawler\\": "" }
},
"target-dir": "Symfony/Component/DomCrawler",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
DomCrawler Component
====================
DomCrawler eases DOM navigation for HTML and XML documents.
If you are familiar with jQuery, DomCrawler is a PHP equivalent:
use Symfony\Component\DomCrawler\Crawler;
$crawler = new Crawler();
$crawler->addContent('<html><body><p>Hello World!</p></body></html>');
print $crawler->filterXPath('descendant-or-self::body/p')->text();
If you are also using the CssSelector component, you can use CSS Selectors
instead of XPath expressions:
use Symfony\Component\DomCrawler\Crawler;
$crawler = new Crawler();
$crawler->addContent('<html><body><p>Hello World!</p></body></html>');
print $crawler->filter('body > p')->text();
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/DomCrawler/
$ composer.phar install
$ phpunit
CREDITS
=======
eZ Components team
------------------
- Sergey Alexeev
- Sebastian Bergmann
- Jan Borsodi
- Raymond Bosman
- Frederik Holljen
- Kore Nordmann
- Derick Rethans
- Vadym Savchuk
- Tobias Schlitt
- Alexandru Stanoi
eZ Components Licence
=====================
Copyright (c) 2005, 2006, 2007, eZ Systems A.S.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of eZ Systems A.S. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<?php
$dir = dirname( __FILE__ );
$dirParts = explode( '/', $dir );
switch ( $dirParts[count( $dirParts ) - 3] )
{
case 'doc': require_once 'ezc/Base/base.php'; break; // pear
case 'trunk': require_once "$dir/../../Base/src/base.php"; break; // svn
default: require_once "$dir/../../Base/src/base.php"; break; // bundle
}
/**
* Autoload ezc classes
*
* @param string $className
*/
function __autoload( $className )
{
ezcBase::autoload( $className );
}
?>
eZ Components - File
~~~~~~~~~~~~~~~~~~~~
.. contents:: Table of Contents
Introduction
============
The File component is now **deprecated**. Instead use the ezcBaseFile class
from the Base package. Please refer to the Base_ component introduction
for the tutorial. The classes in this component still exist because
of backwards compatibility reasons.
.. _Base: introduction_Base.html
More information
================
For more information, see the ezcBaseFile API documentation.
..
Local Variables:
mode: rst
fill-column: 79
End:
vim: et syn=rst tw=79
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.3.0
-----
* added RequestContext::getQueryString()
2.2.0
-----
* [DEPRECATION] Several route settings have been renamed (the old ones will be removed in 3.0):
* The `pattern` setting for a route has been deprecated in favor of `path`
* The `_scheme` and `_method` requirements have been moved to the `schemes` and `methods` settings
Before:
```
article_edit:
pattern: /article/{id}
requirements: { '_method': 'POST|PUT', '_scheme': 'https', 'id': '\d+' }
<route id="article_edit" pattern="/article/{id}">
<requirement key="_method">POST|PUT</requirement>
<requirement key="_scheme">https</requirement>
<requirement key="id">\d+</requirement>
</route>
$route = new Route();
$route->setPattern('/article/{id}');
$route->setRequirement('_method', 'POST|PUT');
$route->setRequirement('_scheme', 'https');
```
After:
```
article_edit:
path: /article/{id}
methods: [POST, PUT]
schemes: https
requirements: { 'id': '\d+' }
<route id="article_edit" pattern="/article/{id}" methods="POST PUT" schemes="https">
<requirement key="id">\d+</requirement>
</route>
$route = new Route();
$route->setPath('/article/{id}');
$route->setMethods(array('POST', 'PUT'));
$route->setSchemes('https');
```
* [BC BREAK] RouteCollection does not behave like a tree structure anymore but as
a flat array of Routes. So when using PHP to build the RouteCollection, you must
make sure to add routes to the sub-collection before adding it to the parent
collection (this is not relevant when using YAML or XML for Route definitions).
Before:
```
$rootCollection = new RouteCollection();
$subCollection = new RouteCollection();
$rootCollection->addCollection($subCollection);
$subCollection->add('foo', new Route('/foo'));
```
After:
```
$rootCollection = new RouteCollection();
$subCollection = new RouteCollection();
$subCollection->add('foo', new Route('/foo'));
$rootCollection->addCollection($subCollection);
```
Also one must call `addCollection` from the bottom to the top hierarchy.
So the correct sequence is the following (and not the reverse):
```
$childCollection->->addCollection($grandchildCollection);
$rootCollection->addCollection($childCollection);
```
* [DEPRECATION] The methods `RouteCollection::getParent()` and `RouteCollection::getRoot()`
have been deprecated and will be removed in Symfony 2.3.
* [BC BREAK] Misusing the `RouteCollection::addPrefix` method to add defaults, requirements
or options without adding a prefix is not supported anymore. So if you called `addPrefix`
with an empty prefix or `/` only (both have no relevance), like
`addPrefix('', $defaultsArray, $requirementsArray, $optionsArray)`
you need to use the new dedicated methods `addDefaults($defaultsArray)`,
`addRequirements($requirementsArray)` or `addOptions($optionsArray)` instead.
* [DEPRECATION] The `$options` parameter to `RouteCollection::addPrefix()` has been deprecated
because adding options has nothing to do with adding a path prefix. If you want to add options
to all child routes of a RouteCollection, you can use `addOptions()`.
* [DEPRECATION] The method `RouteCollection::getPrefix()` has been deprecated
because it suggested that all routes in the collection would have this prefix, which is
not necessarily true. On top of that, since there is no tree structure anymore, this method
is also useless. Don't worry about performance, prefix optimization for matching is still done
in the dumper, which was also improved in 2.2.0 to find even more grouping possibilities.
* [DEPRECATION] `RouteCollection::addCollection(RouteCollection $collection)` should now only be
used with a single parameter. The other params `$prefix`, `$default`, `$requirements` and `$options`
will still work, but have been deprecated. The `addPrefix` method should be used for this
use-case instead.
Before: `$parentCollection->addCollection($collection, '/prefix', array(...), array(...))`
After:
```
$collection->addPrefix('/prefix', array(...), array(...));
$parentCollection->addCollection($collection);
```
* added support for the method default argument values when defining a @Route
* Adjacent placeholders without separator work now, e.g. `/{x}{y}{z}.{_format}`.
* Characters that function as separator between placeholders are now whitelisted
to fix routes with normal text around a variable, e.g. `/prefix{var}suffix`.
* [BC BREAK] The default requirement of a variable has been changed slightly.
Previously it disallowed the previous and the next char around a variable. Now
it disallows the slash (`/`) and the next char. Using the previous char added
no value and was problematic because the route `/index.{_format}` would be
matched by `/index.ht/ml`.
* The default requirement now uses possessive quantifiers when possible which
improves matching performance by up to 20% because it prevents backtracking
when it's not needed.
* The ConfigurableRequirementsInterface can now also be used to disable the requirements
check on URL generation completely by calling `setStrictRequirements(null)`. It
improves performance in production environment as you should know that params always
pass the requirements (otherwise it would break your link anyway).
* There is no restriction on the route name anymore. So non-alphanumeric characters
are now also allowed.
* [BC BREAK] `RouteCompilerInterface::compile(Route $route)` was made static
(only relevant if you implemented your own RouteCompiler).
* Added possibility to generate relative paths and network paths in the UrlGenerator, e.g.
"../parent-file" and "//example.com/dir/file". The third parameter in
`UrlGeneratorInterface::generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)`
now accepts more values and you should use the constants defined in `UrlGeneratorInterface` for
claritiy. The old method calls with a Boolean parameter will continue to work because they
equal the signature using the constants.
2.1.0
-----
* added RequestMatcherInterface
* added RequestContext::fromRequest()
* the UrlMatcher does not throw a \LogicException anymore when the required
scheme is not the current one
* added TraceableUrlMatcher
* added the possibility to define options, default values and requirements
for placeholders in prefix, including imported routes
* added RouterInterface::getRouteCollection
* [BC BREAK] the UrlMatcher urldecodes the route parameters only once, they
were decoded twice before. Note that the `urldecode()` calls have been
changed for a single `rawurldecode()` in order to support `+` for input
paths.
* added RouteCollection::getRoot method to retrieve the root of a
RouteCollection tree
* [BC BREAK] made RouteCollection::setParent private which could not have
been used anyway without creating inconsistencies
* [BC BREAK] RouteCollection::remove also removes a route from parent
collections (not only from its children)
* added ConfigurableRequirementsInterface that allows to disable exceptions
(and generate empty URLs instead) when generating a route with an invalid
parameter value
{
"name": "symfony/routing",
"type": "library",
"description": "Symfony Routing Component",
"keywords": ["routing", "router", "URL", "URI"],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/config": "~2.2",
"symfony/yaml": "~2.0",
"symfony/expression-language": "~2.4",
"doctrine/annotations": "~1.0",
"psr/log": "~1.0"
},
"suggest": {
"symfony/config": "For using the all-in-one router or any loader",
"symfony/yaml": "For using the YAML loader",
"symfony/expression-language": "For using expression matching",
"doctrine/annotations": "For using the annotation loader"
},
"autoload": {
"psr-0": { "Symfony\\Component\\Routing\\": "" }
},
"target-dir": "Symfony/Component/Routing",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
Routing Component
=================
Routing associates a request with the code that will convert it to a response.
The example below demonstrates how you can set up a fully working routing
system:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$routes = new RouteCollection();
$routes->add('hello', new Route('/hello', array('controller' => 'foo')));
$context = new RequestContext();
// this is optional and can be done without a Request instance
$context->fromRequest(Request::createFromGlobals());
$matcher = new UrlMatcher($routes, $context);
$parameters = $matcher->match('/hello');
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/Routing/
$ composer.phar install
$ phpunit
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.2.0
-----
* added an optional PropertyAccessorInterface parameter to DoctrineType,
EntityType and EntityChoiceList
2.1.0
-----
* added a default implementation of the ManagerRegistry
* added a session storage for Doctrine DBAL
* DoctrineOrmTypeGuesser now guesses "collection" for array Doctrine type
* DoctrineType now caches its choice lists in order to improve performance
* DoctrineType now uses ManagerRegistry::getManagerForClass() if the option "em" is not set
* UniqueEntity validation constraint now accepts a "repositoryMethod" option that will be used to check for uniqueness instead of the default "findBy"
* [BC BREAK] the DbalLogger::log() visibility has been changed from public to
protected
{
"name": "symfony/doctrine-bridge",
"type": "symfony-bridge",
"description": "Symfony Doctrine Bridge",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3",
"doctrine/common": "~2.2"
},
"require-dev": {
"symfony/stopwatch": "~2.2",
"symfony/dependency-injection": "~2.0",
"symfony/form": "~2.2",
"symfony/http-kernel": "~2.2",
"symfony/security": "~2.2",
"symfony/expression-language": "~2.2",
"symfony/validator": "~2.2",
"doctrine/data-fixtures": "1.0.*",
"doctrine/dbal": "~2.2",
"doctrine/orm": "~2.2,>=2.2.3"
},
"suggest": {
"symfony/form": "",
"symfony/validator": "",
"doctrine/data-fixtures": "",
"doctrine/dbal": "",
"doctrine/orm": ""
},
"autoload": {
"psr-0": { "Symfony\\Bridge\\Doctrine\\": "" }
},
"target-dir": "Symfony/Bridge/Doctrine",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
Doctrine Bridge
===============
Provides integration for [Doctrine](http://www.doctrine-project.org/) with
various Symfony2 components.
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Bridge/Doctrine/
$ composer.phar install
$ phpunit
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.1.0
-----
* added StreamingEngineInterface
* added ENT_SUBSTITUTE for the HTML escaper
{
"name": "symfony/templating",
"type": "library",
"description": "Symfony Templating Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"psr/log": "~1.0"
},
"suggest": {
"psr/log": "For using debug logging in loaders"
},
"autoload": {
"psr-0": { "Symfony\\Component\\Templating\\": "" }
},
"target-dir": "Symfony/Component/Templating",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
Templating Component
====================
Templating provides all the tools needed to build any kind of template system.
It provides an infrastructure to load template files and optionally monitor
them for changes. It also provides a concrete template engine implementation
using PHP with additional tools for escaping and separating templates into
blocks and layouts.
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/Templating/
$ composer.phar install
$ phpunit
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.4.0
-----
* moved CSRF implementation to the new Security CSRF sub-component
* deprecated CsrfProviderInterface and its implementations
* deprecated options "csrf_provider" and "intention" in favor of the new options "csrf_token_generator" and "csrf_token_id"
2.3.0
-----
* deprecated FormPerformanceTestCase and FormIntegrationTestCase in the Symfony\Component\Form\Tests namespace and moved them to the Symfony\Component\Form\Test namespace
* deprecated TypeTestCase in the Symfony\Component\Form\Tests\Extension\Core\Type namespace and moved it to the Symfony\Component\Form\Test namespace
* changed FormRenderer::humanize() to humanize also camel cased field name
* added RequestHandlerInterface and FormInterface::handleRequest()
* deprecated passing a Request instance to FormInterface::bind()
* added options "method" and "action" to FormType
* deprecated option "virtual" in favor "inherit_data"
* deprecated VirtualFormAwareIterator in favor of InheritDataAwareIterator
* [BC BREAK] removed the "array" type hint from DataMapperInterface
* improved forms inheriting their parent data to actually return that data from getData(), getNormData() and getViewData()
* added component-level exceptions for various SPL exceptions
changed all uses of the deprecated Exception class to use more specialized exceptions instead
removed NotInitializedException, NotValidException, TypeDefinitionException, TypeLoaderException, CreationException
* added events PRE_SUBMIT, SUBMIT and POST_SUBMIT
* deprecated events PRE_BIND, BIND and POST_BIND
* [BC BREAK] renamed bind() and isBound() in FormInterface to submit() and isSubmitted()
* added methods submit() and isSubmitted() to Form
* deprecated bind() and isBound() in Form
* deprecated AlreadyBoundException in favor of AlreadySubmittedException
* added support for PATCH requests
* [BC BREAK] added initialize() to FormInterface
* [BC BREAK] added getAutoInitialize() to FormConfigInterface
* [BC BREAK] added setAutoInitialize() to FormConfigBuilderInterface
* [BC BREAK] initialization for Form instances added to a form tree must be manually disabled
* PRE_SET_DATA is now guaranteed to be called after children were added by the form builder,
unless FormInterface::setData() is called manually
* fixed CSRF error message to be translated
* custom CSRF error messages can now be set through the "csrf_message" option
* fixed: expanded single-choice fields now show a radio button for the empty value
2.2.0
-----
* TrimListener now removes unicode whitespaces
* deprecated getParent(), setParent() and hasParent() in FormBuilderInterface
* FormInterface::add() now accepts a FormInterface instance OR a field's name, type and options
* removed special characters between the choice or text fields of DateType unless
the option "format" is set to a custom value
* deprecated FormException and introduced ExceptionInterface instead
* [BC BREAK] FormException is now an interface
* protected FormBuilder methods from being called when it is turned into a FormConfigInterface with getFormConfig()
* [BC BREAK] inserted argument `$message` in the constructor of `FormError`
* the PropertyPath class and related classes were moved to a dedicated
PropertyAccess component. During the move, InvalidPropertyException was
renamed to NoSuchPropertyException. FormUtil was split: FormUtil::singularify()
can now be found in Symfony\Component\PropertyAccess\StringUtil. The methods
getValue() and setValue() from PropertyPath were extracted into a new class
PropertyAccessor.
* added an optional PropertyAccessorInterface parameter to FormType,
ObjectChoiceList and PropertyPathMapper
* [BC BREAK] PropertyPathMapper and FormType now have a constructor
* [BC BREAK] setting the option "validation_groups" to ``false`` now disables validation
instead of assuming group "Default"
2.1.0
-----
* [BC BREAK] ``read_only`` field attribute now renders as ``readonly="readonly"``, use ``disabled`` instead
* [BC BREAK] child forms now aren't validated anymore by default
* made validation of form children configurable (new option: cascade_validation)
* added support for validation groups as callbacks
* made the translation catalogue configurable via the "translation_domain" option
* added Form::getErrorsAsString() to help debugging forms
* allowed setting different options for RepeatedType fields (like the label)
* added support for empty form name at root level, this enables rendering forms
without form name prefix in field names
* [BC BREAK] form and field names must start with a letter, digit or underscore
and only contain letters, digits, underscores, hyphens and colons
* [BC BREAK] changed default name of the prototype in the "collection" type
from "$$name$$" to "\__name\__". No dollars are appended/prepended to custom
names anymore.
* [BC BREAK] improved ChoiceListInterface
* [BC BREAK] added SimpleChoiceList and LazyChoiceList as replacement of
ArrayChoiceList
* added ChoiceList and ObjectChoiceList to use objects as choices
* [BC BREAK] removed EntitiesToArrayTransformer and EntityToIdTransformer.
The former has been replaced by CollectionToArrayTransformer in combination
with EntityChoiceList, the latter is not required in the core anymore.
* [BC BREAK] renamed
* ArrayToBooleanChoicesTransformer to ChoicesToBooleanArrayTransformer
* ScalarToBooleanChoicesTransformer to ChoiceToBooleanArrayTransformer
* ArrayToChoicesTransformer to ChoicesToValuesTransformer
* ScalarToChoiceTransformer to ChoiceToValueTransformer
to be consistent with the naming in ChoiceListInterface.
They were merged into ChoiceList and have no public equivalent anymore.
* choice fields now throw a FormException if neither the "choices" nor the
"choice_list" option is set
* the radio type is now a child of the checkbox type
* the collection, choice (with multiple selection) and entity (with multiple
selection) types now make use of addXxx() and removeXxx() methods in your
model if you set "by_reference" to false. For a custom, non-recognized
singular form, set the "property_path" option like this: "plural|singular"
* forms now don't create an empty object anymore if they are completely
empty and not required. The empty value for such forms is null.
* added constant Guess::VERY_HIGH_CONFIDENCE
* [BC BREAK] The methods `add`, `remove`, `setParent`, `bind` and `setData`
in class Form now throw an exception if the form is already bound
* fields of constrained classes without a NotBlank or NotNull constraint are
set to not required now, as stated in the docs
* fixed TimeType and DateTimeType to not display seconds when "widget" is
"single_text" unless "with_seconds" is set to true
* checkboxes of in an expanded multiple-choice field don't include the choice
in their name anymore. Their names terminate with "[]" now.
* deprecated FormValidatorInterface and substituted its implementations
by event subscribers
* simplified CSRF protection and removed the csrf type
* deprecated FieldType and merged it into FormType
* added new option "compound" that lets you switch between field and form behavior
* [BC BREAK] renamed theme blocks
* "field_*" to "form_*"
* "field_widget" to "form_widget_simple"
* "widget_choice_options" to "choice_widget_options"
* "generic_label" to "form_label"
* added theme blocks "form_widget_compound", "choice_widget_expanded" and
"choice_widget_collapsed" to make theming more modular
* ValidatorTypeGuesser now guesses "collection" for array type constraint
* added method `guessPattern` to FormTypeGuesserInterface to guess which pattern to use in the HTML5 attribute "pattern"
* deprecated method `guessMinLength` in favor of `guessPattern`
* labels don't display field attributes anymore. Label attributes can be
passed in the "label_attr" option/variable
* added option "mapped" which should be used instead of setting "property_path" to false
* [BC BREAK] "data_class" now *must* be set if a form maps to an object and should be left empty otherwise
* improved error mapping on forms
* dot (".") rules are now allowed to map errors assigned to a form to
one of its children
* errors are not mapped to unsynchronized forms anymore
* [BC BREAK] changed Form constructor to accept a single `FormConfigInterface` object
* [BC BREAK] changed argument order in the FormBuilder constructor
* added Form method `getViewData`
* deprecated Form methods
* `getTypes`
* `getErrorBubbling`
* `getNormTransformers`
* `getClientTransformers`
* `getAttribute`
* `hasAttribute`
* `getClientData`
* added FormBuilder methods
* `getTypes`
* `addViewTransformer`
* `getViewTransformers`
* `resetViewTransformers`
* `addModelTransformer`
* `getModelTransformers`
* `resetModelTransformers`
* deprecated FormBuilder methods
* `prependClientTransformer`
* `appendClientTransformer`
* `getClientTransformers`
* `resetClientTransformers`
* `prependNormTransformer`
* `appendNormTransformer`
* `getNormTransformers`
* `resetNormTransformers`
* deprecated the option "validation_constraint" in favor of the new
option "constraints"
* removed superfluous methods from DataMapperInterface
* `mapFormToData`
* `mapDataToForm`
* added `setDefaultOptions` to FormTypeInterface and FormTypeExtensionInterface
which accepts an OptionsResolverInterface instance
* deprecated the methods `getDefaultOptions` and `getAllowedOptionValues`
in FormTypeInterface and FormTypeExtensionInterface
* options passed during construction can now be accessed from FormConfigInterface
* added FormBuilderInterface and FormConfigEditorInterface
* [BC BREAK] the method `buildForm` in FormTypeInterface and FormTypeExtensionInterface
now receives a FormBuilderInterface instead of a FormBuilder instance
* [BC BREAK] the method `buildViewBottomUp` was renamed to `finishView` in
FormTypeInterface and FormTypeExtensionInterface
* [BC BREAK] the options array is now passed as last argument of the
methods
* `buildView`
* `finishView`
in FormTypeInterface and FormTypeExtensionInterface
* [BC BREAK] no options are passed to `getParent` of FormTypeInterface anymore
* deprecated DataEvent and FilterDataEvent in favor of the new FormEvent which is
now passed to all events thrown by the component
* FormEvents::BIND now replaces FormEvents::BIND_NORM_DATA
* FormEvents::PRE_SET_DATA now replaces FormEvents::SET_DATA
* FormEvents::PRE_BIND now replaces FormEvents::BIND_CLIENT_DATA
* deprecated FormEvents::SET_DATA, FormEvents::BIND_CLIENT_DATA and
FormEvents::BIND_NORM_DATA
* [BC BREAK] reversed the order of the first two arguments to `createNamed`
and `createNamedBuilder` in `FormFactoryInterface`
* deprecated `getChildren` in Form and FormBuilder in favor of `all`
* deprecated `hasChildren` in Form and FormBuilder in favor of `count`
* FormBuilder now implements \IteratorAggregate
* [BC BREAK] compound forms now always need a data mapper
* FormBuilder now maintains the order when explicitly adding form builders as children
* ChoiceType now doesn't add the empty value anymore if the choices already contain an empty element
* DateType, TimeType and DateTimeType now show empty values again if not required
* [BC BREAK] fixed rendering of errors for DateType, BirthdayType and similar ones
* [BC BREAK] fixed: form constraints are only validated if they belong to the validated group
* deprecated `bindRequest` in `Form` and replaced it by a listener to FormEvents::PRE_BIND
* fixed: the "data" option supersedes default values from the model
* changed DateType to refer to the "format" option for calculating the year and day choices instead
of padding them automatically
* [BC BREAK] DateType defaults to the format "yyyy-MM-dd" now if the widget is
"single_text", in order to support the HTML 5 date field out of the box
* added the option "format" to DateTimeType
* [BC BREAK] DateTimeType now outputs RFC 3339 dates by default, as generated and
consumed by HTML5 browsers, if the widget is "single_text"
* deprecated the options "data_timezone" and "user_timezone" in DateType, DateTimeType and TimeType
and renamed them to "model_timezone" and "view_timezone"
* fixed: TransformationFailedExceptions thrown in the model transformer are now caught by the form
* added FormRegistryInterface, ResolvedFormTypeInterface and ResolvedFormTypeFactoryInterface
* deprecated FormFactory methods
* `addType`
* `hasType`
* `getType`
* [BC BREAK] FormFactory now expects a FormRegistryInterface and a ResolvedFormTypeFactoryInterface as constructor argument
* [BC BREAK] The method `createBuilder` in FormTypeInterface is not supported anymore for performance reasons
* [BC BREAK] Removed `setTypes` from FormBuilder
* deprecated AbstractType methods
* `getExtensions`
* `setExtensions`
* ChoiceType now caches its created choice lists to improve performance
* [BC BREAK] Rows of a collection field cannot be themed individually anymore. All rows in the collection
field now have the same block names, which contains "entry" where it previously contained the row index.
* [BC BREAK] When registering a type through the DI extension, the tag alias has to match the actual type name.
* added FormRendererInterface, FormRendererEngineInterface and implementations of these interfaces
* [BC BREAK] removed the following methods from FormUtil:
* `toArrayKey`
* `toArrayKeys`
* `isChoiceGroup`
* `isChoiceSelected`
* [BC BREAK] renamed method `renderBlock` in FormHelper to `block` and changed its signature
* made FormView properties public and deprecated their accessor methods
* made the normalized data of a form accessible in the template through the variable "form.vars.data"
* made the original data of a choice accessible in the template through the property "choice.data"
* added convenience class Forms and FormFactoryBuilderInterface
{
"name": "symfony/form",
"type": "library",
"description": "Symfony Form Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3",
"symfony/event-dispatcher": "~2.1",
"symfony/intl": "~2.3",
"symfony/options-resolver": "~2.1",
"symfony/property-access": "~2.3"
},
"require-dev": {
"symfony/validator": "~2.2",
"symfony/http-foundation": "~2.2",
"symfony/security-csrf": "~2.4"
},
"suggest": {
"symfony/validator": "For form validation.",
"symfony/security-csrf": "For protecting forms against CSRF attacks.",
"symfony/twig-bridge": "For templating with Twig.",
"symfony/framework-bundle": "For templating with PHP."
},
"autoload": {
"psr-0": { "Symfony\\Component\\Form\\": "" }
},
"target-dir": "Symfony/Component/Form",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
Form Component
==============
Form provides tools for defining forms, rendering and mapping request data to
related models. Furthermore it provides integration with the Validation
component.
Resources
---------
Silex integration:
https://github.com/fabpot/Silex/blob/master/src/Silex/Provider/FormServiceProvider.php
Documentation:
http://symfony.com/doc/2.4/book/forms.html
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/Form/
$ composer.phar install
$ phpunit
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.4.0
-----
* added the ability to define an idle timeout
2.3.0
-----
* added ProcessUtils::escapeArgument() to fix the bug in escapeshellarg() function on Windows
* added Process::signal()
* added Process::getPid()
* added support for a TTY mode
2.2.0
-----
* added ProcessBuilder::setArguments() to reset the arguments on a builder
* added a way to retrieve the standard and error output incrementally
* added Process:restart()
2.1.0
-----
* added support for non-blocking processes (start(), wait(), isRunning(), stop())
* enhanced Windows compatibility
* added Process::getExitCodeText() that returns a string representation for
the exit code returned by the process
* added ProcessBuilder
{
"name": "symfony/process",
"type": "library",
"description": "Symfony Process Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3"
},
"autoload": {
"psr-0": { "Symfony\\Component\\Process\\": "" }
},
"target-dir": "Symfony/Component/Process",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
Process Component
=================
Process executes commands in sub-processes.
In this example, we run a simple directory listing and get the result back:
use Symfony\Component\Process\Process;
$process = new Process('ls -lsa');
$process->setTimeout(3600);
$process->run();
if (!$process->isSuccessful()) {
throw new RuntimeException($process->getErrorOutput());
}
print $process->getOutput();
You can think that this is easy to achieve with plain PHP but it's not especially
if you want to take care of the subtle differences between the different platforms.
And if you want to be able to get some feedback in real-time, just pass an
anonymous function to the ``run()`` method and you will get the output buffer
as it becomes available:
use Symfony\Component\Process\Process;
$process = new Process('ls -lsa');
$process->run(function ($type, $buffer) {
if ('err' === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
That's great if you want to execute a long running command (like rsync-ing files to a
remote server) and give feedback to the user in real-time.
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/XXX/
$ composer.phar install
$ phpunit
Copyright 1997-2017 The PHP Group
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Net_Socket - Network Socket Interface
[](https://travis-ci.org/pear/Net_Socket)
Net_Socket is a class interface to TCP sockets. It provides blocking
and non-blocking operation, with different reading and writing modes
(byte-wise, block-wise, line-wise and special formats like network
byte-order ip addresses).
[Homepage](http://pear.php.net/package/Net_Socket/)
## Installation
For a PEAR installation that downloads from the PEAR channel:
`$ pear install pear/net_socket`
For a PEAR installation from a previously downloaded tarball:
`$ pear install Net_Socket-*.tgz`
For a PEAR installation from a code clone:
`$ pear install package.xml`
For a local composer installation:
`$ composer install`
To add as a dependency to your composer-managed application:
`$composer require pear/net_socket`
## Tests
Run the tests from a local composer installation:
`$ ./vendor/bin/phpunit`
## License
BSD-2 license
Copyright (c) 2004-2014 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
CHANGELOG
=========
2.3.0
-----
* [BC BREAK] `Client::followRedirect()` won't redirect responses with
a non-3xx Status Code and `Location` header anymore, as per
http://tools.ietf.org/html/rfc2616#section-14.30
* added `Client::getInternalRequest()` and `Client::getInternalResponse()` to
have access to the BrowserKit internal request and response objects
2.1.0
-----
* [BC BREAK] The CookieJar internals have changed to allow cookies with the
same name on different sub-domains/sub-paths
{
"name": "symfony/browser-kit",
"type": "library",
"description": "Symfony BrowserKit Component",
"keywords": [],
"homepage": "http://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"require": {
"php": ">=5.3.3",
"symfony/dom-crawler": "~2.0"
},
"require-dev": {
"symfony/process": "~2.0",
"symfony/css-selector": "~2.0"
},
"suggest": {
"symfony/process": ""
},
"autoload": {
"psr-0": { "Symfony\\Component\\BrowserKit\\": "" }
},
"target-dir": "Symfony/Component/BrowserKit",
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
}
}
BrowserKit Component
====================
BrowserKit simulates the behavior of a web browser.
The component only provide an abstract client and does not provide any
"default" backend for the HTTP layer.
Resources
---------
For a simple implementation of a browser based on an HTTP layer, have a look
at [Goutte](https://github.com/fabpot/Goutte).
For an implementation based on HttpKernelInterface, have a look at the
[Client](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/Client.php)
provided by the HttpKernel component.
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/BrowserKit/
$ composer.phar install
$ phpunit
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Examples (file #1)
*
* several examples for the methods of XML_Util
*
* PHP versions 4 and 5
*
* LICENSE:
*
* Copyright (c) 2003-2008 Stephan Schmidt <schst@php.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category XML
* @package XML_Util
* @subpackage Examples
* @author Stephan Schmidt <schst@php.net>
* @copyright 2003-2008 Stephan Schmidt <schst@php.net>
* @license http://opensource.org/licenses/bsd-license New BSD License
* @version CVS: $Id$
* @link http://pear.php.net/package/XML_Util
*/
/**
* set error level
*/
error_reporting(E_ALL);
require_once 'XML/Util.php';
/**
* replacing XML entities
*/
print 'replace XML entities:<br>';
print XML_Util::replaceEntities('This string contains < & >.');
print "\n<br><br>\n";
/**
* reversing XML entities
*/
print 'replace XML entities:<br>';
print XML_Util::reverseEntities('This string contains < & >.');
print "\n<br><br>\n";
/**
* building XML declaration
*/
print 'building XML declaration:<br>';
print htmlspecialchars(XML_Util::getXMLDeclaration());
print "\n<br><br>\n";
print 'building XML declaration with additional attributes:<br>';
print htmlspecialchars(XML_Util::getXMLDeclaration('1.0', 'UTF-8', true));
print "\n<br><br>\n";
/**
* building document type declaration
*/
print 'building DocType declaration:<br>';
print htmlspecialchars(XML_Util::getDocTypeDeclaration('package',
'http://pear.php.net/dtd/package-1.0'));
print "\n<br><br>\n";
print 'building DocType declaration with public ID (does not exist):<br>';
print htmlspecialchars(XML_Util::getDocTypeDeclaration('package',
array('uri' => 'http://pear.php.net/dtd/package-1.0',
'id' => '-//PHP//PEAR/DTD PACKAGE 0.1')));
print "\n<br><br>\n";
print 'building DocType declaration with internal DTD:<br>';
print '<pre>';
print htmlspecialchars(XML_Util::getDocTypeDeclaration('package',
'http://pear.php.net/dtd/package-1.0',
'<!ELEMENT additionalInfo (#PCDATA)>'));
print '</pre>';
print "\n<br><br>\n";
/**
* creating an attribute string
*/
$att = array(
'foo' => 'bar',
'argh' => 'tomato'
);
print 'converting array to string:<br>';
print XML_Util::attributesToString($att);
print "\n<br><br>\n";
/**
* creating an attribute string with linebreaks
*/
$att = array(
'foo' => 'bar',
'argh' => 'tomato'
);
print 'converting array to string (including line breaks):<br>';
print '<pre>';
print XML_Util::attributesToString($att, true, true);
print '</pre>';
print "\n<br><br>\n";
/**
* splitting a qualified tag name
*/
print 'splitting qualified tag name:<br>';
print '<pre>';
print_r(XML_Util::splitQualifiedName('xslt:stylesheet'));
print '</pre>';
print "\n<br>\n";
/**
* splitting a qualified tag name (no namespace)
*/
print 'splitting qualified tag name (no namespace):<br>';
print '<pre>';
print_r(XML_Util::splitQualifiedName('foo'));
print '</pre>';
print "\n<br>\n";
/**
* splitting a qualified tag name (no namespace, but default namespace specified)
*/
print 'splitting qualified tag name '
. '(no namespace, but default namespace specified):<br>';
print '<pre>';
print_r(XML_Util::splitQualifiedName('foo', 'bar'));
print '</pre>';
print "\n<br>\n";
/**
* verifying XML names
*/
print 'verifying \'My private tag\':<br>';
print '<pre>';
print_r(XML_Util::isValidname('My Private Tag'));
print '</pre>';
print "\n<br><br>\n";
print 'verifying \'-MyTag\':<br>';
print '<pre>';
print_r(XML_Util::isValidname('-MyTag'));
print '</pre>';
print "\n<br><br>\n";
/**
* creating an XML tag
*/
$tag = array(
'namespace' => 'foo',
'localPart' => 'bar',
'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'),
'content' => 'I\'m inside the tag'
);
print 'creating a tag with namespace and local part:<br>';
print htmlentities(XML_Util::createTagFromArray($tag));
print "\n<br><br>\n";
/**
* creating an XML tag
*/
$tag = array(
'qname' => 'foo:bar',
'namespaceUri' => 'http://foo.com',
'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'),
'content' => 'I\'m inside the tag'
);
print 'creating a tag with qualified name and namespaceUri:<br>';
print htmlentities(XML_Util::createTagFromArray($tag));
print "\n<br><br>\n";
/**
* creating an XML tag
*/
$tag = array(
'qname' => 'bar',
'namespaceUri' => 'http://foo.com',
'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable')
);
print 'creating an empty tag without namespace but namespace Uri:<br>';
print htmlentities(XML_Util::createTagFromArray($tag));
print "\n<br><br>\n";
/**
* creating an XML tag with more namespaces
*/
$tag = array(
'namespace' => 'foo',
'localPart' => 'bar',
'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'),
'content' => 'I\'m inside the tag',
'namespaces' => array(
'bar' => 'http://bar.com',
'pear' => 'http://pear.php.net',
)
);
print 'creating an XML tag with more namespaces:<br />';
print htmlentities(XML_Util::createTagFromArray($tag));
print "\n<br><br>\n";
/**
* creating an XML tag with a CData Section
*/
$tag = array(
'qname' => 'foo',
'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'),
'content' => 'I\'m inside the tag'
);
print 'creating a tag with CData section:<br>';
print htmlentities(XML_Util::createTagFromArray($tag, XML_UTIL_CDATA_SECTION));
print "\n<br><br>\n";
/**
* creating an XML tag with a CData Section
*/
$tag = array(
'qname' => 'foo',
'attributes' => array('key' => 'value', 'argh' => 't�t�'),
'content' =>
'Also XHTML-tags can be created '
. 'and HTML entities can be replaced � � � � <>.'
);
print 'creating a tag with HTML entities:<br>';
print htmlentities(XML_Util::createTagFromArray($tag, XML_UTIL_ENTITIES_HTML));
print "\n<br><br>\n";
/**
* creating an XML tag with createTag
*/
print 'creating a tag with createTag:<br>';
print htmlentities(XML_Util::createTag('myNs:myTag',
array('foo' => 'bar'),
'This is inside the tag',
'http://www.w3c.org/myNs#'));
print "\n<br><br>\n";
/**
* trying to create an XML tag with an array as content
*/
$tag = array(
'qname' => 'bar',
'content' => array('foo' => 'bar')
);
print 'trying to create an XML tag with an array as content:<br>';
print '<pre>';
print_r(XML_Util::createTagFromArray($tag));
print '</pre>';
print "\n<br><br>\n";
/**
* trying to create an XML tag without a name
*/
$tag = array(
'attributes' => array('foo' => 'bar'),
);
print 'trying to create an XML tag without a name:<br>';
print '<pre>';
print_r(XML_Util::createTagFromArray($tag));
print '</pre>';
print "\n<br><br>\n";
?>
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* Examples (file #2)
*
* several examples for the methods of XML_Util
*
* PHP versions 4 and 5
*
* LICENSE:
*
* Copyright (c) 2003-2008 Stephan Schmidt <schst@php.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @category XML
* @package XML_Util
* @subpackage Examples
* @author Stephan Schmidt <schst@php.net>
* @copyright 2003-2008 Stephan Schmidt <schst@php.net>
* @license http://opensource.org/licenses/bsd-license New BSD License
* @version CVS: $Id$
* @link http://pear.php.net/package/XML_Util
*/
/**
* set error level
*/
error_reporting(E_ALL);
require_once 'XML/Util.php';
/**
* creating a start element
*/
print 'creating a start element:<br>';
print htmlentities(XML_Util::createStartElement('myNs:myTag',
array('foo' => 'bar'), 'http://www.w3c.org/myNs#'));
print "\n<br><br>\n";
/**
* creating a start element
*/
print 'creating a start element:<br>';
print htmlentities(XML_Util::createStartElement('myTag',
array(), 'http://www.w3c.org/myNs#'));
print "\n<br><br>\n";
/**
* creating a start element
*/
print 'creating a start element:<br>';
print '<pre>';
print htmlentities(XML_Util::createStartElement('myTag',
array('foo' => 'bar', 'argh' => 'tomato'),
'http://www.w3c.org/myNs#', true));
print '</pre>';
print "\n<br><br>\n";
/**
* creating an end element
*/
print 'creating an end element:<br>';
print htmlentities(XML_Util::createEndElement('myNs:myTag'));
print "\n<br><br>\n";
/**
* creating a CData section
*/
print 'creating a CData section:<br>';
print htmlentities(XML_Util::createCDataSection('I am content.'));
print "\n<br><br>\n";
/**
* creating a comment
*/
print 'creating a comment:<br>';
print htmlentities(XML_Util::createComment('I am a comment.'));
print "\n<br><br>\n";
/**
* creating an XML tag with multiline mode
*/
$tag = array(
'qname' => 'foo:bar',
'namespaceUri' => 'http://foo.com',
'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'),
'content' => 'I\'m inside the tag & contain dangerous chars'
);
print 'creating a tag with qualified name and namespaceUri:<br>';
print '<pre>';
print htmlentities(XML_Util::createTagFromArray($tag,
XML_UTIL_REPLACE_ENTITIES, true));
print '</pre>';
print "\n<br><br>\n";
/**
* create an attribute string without replacing the entities
*/
$atts = array('series' => 'Starsky & Hutch', 'channel' => 'ABC');
print 'creating a attribute string, '
. 'entities in values already had been replaced:<br>';
print htmlentities(XML_Util::attributesToString($atts,
true, false, false, false, XML_UTIL_ENTITIES_NONE));
print "\n<br><br>\n";
/**
* using the array-syntax for attributesToString()
*/
$atts = array('series' => 'Starsky & Hutch', 'channel' => 'ABC');
print 'using the array-syntax for attributesToString()<br>';
print htmlentities(XML_Util::attributesToString($atts,
array('entities' => XML_UTIL_ENTITIES_NONE)));
print "\n<br><br>\n";
?>
<?php
/**
* Example for the usage of ezcConsoleOutput class.
*
* @package ConsoleTools
* @version 1.6.1
* @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
* @license http://ez.no/licenses/new_bsd New BSD License
*/
require_once 'Base/src/base.php';
/**
* Autoload ezc classes
*
* @param string $className
*/
function __autoload( $className )
{
ezcBase::autoload( $className );
}
// Create the output handler
$out = new ezcConsoleOutput();
// Set the verbosity to level 10
$out->options->verbosityLevel = 10;
// Enable auto wrapping of lines after 40 characters
$out->options->autobreak = 40;
// Set the color of the default output format to green
$out->formats->default->color = 'green';
// Set the color of the output format named 'success' to white
$out->formats->success->color = 'white';
// Set the style of the output format named 'success' to bold
$out->formats->success->style = array( 'bold' );
// Set the color of the output format named 'failure' to red
$out->formats->failure->color = 'red';
// Set the style of the output format named 'failure' to bold
$out->formats->failure->style = array( 'bold' );
// Set the background color of the output format named 'failure' to blue
$out->formats->failure->bgcolor = 'blue';
// Output text with default format
$out->outputText( 'This is default text ' );
// Output text with format 'success'
$out->outputText( 'including success message', 'success' );
// Some more output with default output.
$out->outputText( "and a manual linebreak.\n" );
// Manipulate the later output
$out->formats->success->color = 'green';
$out->formats->default->color = 'blue';
// This is visible, since we set verboseLevel to 10, and printed in default format (now blue)
$out->outputText( "Some verbose output.\n", null, 10 );
// This is not visible, since we set verboseLevel to 10
$out->outputText( "Some more verbose output.\n", null, 20 );
// This is visible, since we set verboseLevel to 10, and printed in format 'failure'
$out->outputText( "And some not so verbose, failure output.\n", 'failure', 5 );
?>
<?php
/**
* Example for the usage of ezcConsoleProgressbar class.
*
* @package ConsoleTools
* @version 1.6.1
* @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
* @license http://ez.no/licenses/new_bsd New BSD License
*/
require_once 'Base/src/base.php';
/**
* Autoload ezc classes
*
* @param string $className
*/
function __autoload( $className )
{
ezcBase::autoload( $className );
}
$out = new ezcConsoleOutput();
$out->formats->red->color = "red";
// Create progress bar itself
$progress = new ezcConsoleProgressbar( $out, 100, array( 'step' => 5 ) );
$progress->options->emptyChar = '-';
$progress->options->progressChar = $out->formatText('>', "red");
$progress->options->formatString = "Uploading file </tmp/foobar.tar.bz2>: %act%/%max% kb [%bar%]";
// Perform actions
$i = 0;
while( $i++ < 20 )
{
// Do whatever you want to indicate progress for
usleep( mt_rand( 20000, 2000000 ) );
// Advance the progressbar by one step ( uploading 5k per run )
$progress->advance();
}
// Finish progress bar and jump to next line.
$progress->finish();
$out->outputText( "Successfully uploaded </tmp/foobar.tar.bz2>.\n", 'success' );
/*
OUTPUT: (sequential, will be printed into 1 line and updated in reallife)
Uploading file </tmp/foobar.tar.bz2>: 5/100 kb [++#----------------------------------------------]
Uploading file </tmp/foobar.tar.bz2>: 10/100 kb [+++++#-------------------------------------------]
Uploading file </tmp/foobar.tar.bz2>: 15/100 kb [++++++++#----------------------------------------]
Uploading file </tmp/foobar.tar.bz2>: 20/100 kb [+++++++++++#-------------------------------------]
Uploading file </tmp/foobar.tar.bz2>: 25/100 kb [++++++++++++++#----------------------------------]
Uploading file </tmp/foobar.tar.bz2>: 30/100 kb [+++++++++++++++++#-------------------------------]
Uploading file </tmp/foobar.tar.bz2>: 35/100 kb [++++++++++++++++++++#----------------------------]
Uploading file </tmp/foobar.tar.bz2>: 40/100 kb [+++++++++++++++++++++++#-------------------------]
Uploading file </tmp/foobar.tar.bz2>: 45/100 kb [++++++++++++++++++++++++++#----------------------]
Uploading file </tmp/foobar.tar.bz2>: 50/100 kb [+++++++++++++++++++++++++++++#-------------------]
Uploading file </tmp/foobar.tar.bz2>: 55/100 kb [++++++++++++++++++++++++++++++++#----------------]
Uploading file </tmp/foobar.tar.bz2>: 60/100 kb [+++++++++++++++++++++++++++++++++++#-------------]
Uploading file </tmp/foobar.tar.bz2>: 65/100 kb [++++++++++++++++++++++++++++++++++++++#----------]
Uploading file </tmp/foobar.tar.bz2>: 70/100 kb [+++++++++++++++++++++++++++++++++++++++++#-------]
Uploading file </tmp/foobar.tar.bz2>: 75/100 kb [++++++++++++++++++++++++++++++++++++++++++++#----]
Uploading file </tmp/foobar.tar.bz2>: 80/100 kb [+++++++++++++++++++++++++++++++++++++++++++++++#-]
Uploading file </tmp/foobar.tar.bz2>: 85/100 kb [++++++++++++++++++++++++++++++++++++++++++++++++#]
Uploading file </tmp/foobar.tar.bz2>: 90/100 kb [++++++++++++++++++++++++++++++++++++++++++++++++#]
Uploading file </tmp/foobar.tar.bz2>: 95/100 kb [++++++++++++++++++++++++++++++++++++++++++++++++#]
Uploading file </tmp/foobar.tar.bz2>: 100/100 kb [++++++++++++++++++++++++++++++++++++++++++++++++#]
Uploading file </tmp/foobar.tar.bz2>: 100/100 kb [++++++++++++++++++++++++++++++++++++++++++++++++#]Successfully uploaded </tmp/foobar.tar.bz2>.
*/
?>
CREDITS
=======
eZ Components team
------------------
- Sergey Alexeev
- Sebastian Bergmann
- Jan Borsodi
- Raymond Bosman
- Frederik Holljen
- Kore Nordmann
- Derick Rethans
- Vadym Savchuk
- Tobias Schlitt
- Alexandru Stanoi
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$question = ezcConsoleQuestionDialog::YesNoQuestion(
$output,
"Do you want to proceed?",
"y"
);
do
{
echo "\nSome action performed...\n\n";
}
while ( ezcConsoleDialogViewer::displayDialog( $question ) !== "n" );
echo "Goodbye!\n";
?>
eZ Components Licence
=====================
New BSD Licence
---------------
Copyright (c) 2005-2008, eZ Systems A.S.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of eZ Systems A.S. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$question = new ezcConsoleQuestionDialog( $output );
$question->options->text = "Do you want to proceed?";
$question->options->showResults = true;
$question->options->validator = new ezcConsoleQuestionDialogCollectionValidator(
array( "y", "n" ),
"y",
ezcConsoleQuestionDialogCollectionValidator::CONVERT_LOWER
);
do
{
echo "\nSome action performed...\n\n";
}
while ( ezcConsoleDialogViewer::displayDialog( $question ) !== "n" );
echo "Goodbye!\n";
?>
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$output->formats->success->color = 'green';
$output->formats->failure->color = 'red';
$options = array(
'successChar' => $output->formatText( '+', 'success' ),
'failureChar' => $output->formatText( '-', 'failure' ),
);
$status = new ezcConsoleStatusbar( $output, $options );
for ( $i = 0; $i < 120; $i++ )
{
$nextStatus = ( bool )mt_rand( 0,1 );
$status->add( $nextStatus );
usleep( mt_rand( 200, 2000 ) );
}
$output->outputLine();
$output->outputLine( 'Successes: ' . $status->getSuccessCount() . ', Failures: ' . $status->getFailureCount() );
?>
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$output->formats->info->color = 'blue';
$output->formats->info->style = array( 'bold' );
$output->setOptions(
array(
'autobreak' => 78,
'verbosityLevel' => 3
)
);
$output->outputLine( 'This is a very very long info text. It has so much information in '.
'it, that it will definitly not fit into 1 line. Therefore, '.
'ezcConsoleOutput will automatically wrap the line for us.', 'info' );
$output->outputLine();
$output->outputLine( 'This verbose information will currently not be displayed.', 'info', 10 );
$output->outputLine( 'But this verbose information will be displayed.', 'info', 2 );
?>
<?php
/**
* Example for the usage of ezcConsoleTable class.
*
* @package ConsoleTools
* @version 1.6.1
* @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
* @license http://ez.no/licenses/new_bsd New BSD License
*/
require_once 'Base/src/base.php';
/**
* Autoload ezc classes
*
* @param string $className
*/
function __autoload( $className )
{
ezcBase::autoload( $className );
}
// Initialize the console output handler
$out = new ezcConsoleOutput();
// Define a new format "headline"
$out->formats->headline->color = 'red';
$out->formats->headline->style = array( 'bold' );
// Define a new format "sum"
$out->formats->sum->color = 'blue';
$out->formats->sum->style = array( 'negative' );
// Create a new table
$table = new ezcConsoleTable( $out, 60 );
// Create first row and in it the first cell
$table[0][0]->content = 'Headline 1';
// Create 3 more cells in row 0
for ( $i = 2; $i < 5; $i++ )
{
$table[0][]->content = "Headline $i";
}
$data = array( 1, 2, 3, 4 );
// Create some more data in the table...
foreach ( $data as $value )
{
// Create a new row each time and set it's contents to the actual value
$table[][0]->content = "$value";
}
// Set another border format for our headline row
$table[0]->borderFormat = 'headline';
// Set the content format for all cells of the 3rd row to "sum"
$table[2]->format = 'sum';
$table->outputTable();
echo "\n";
/*
RESULT (without color):
+------------+------------+------------+------------+ //
| Headline 1 | Headline 2 | Headline 3 | Headline 4 | // Red bordered line
+------------+------------+------------+------------+ //
| 1 | | | |
+------------+------------+------------+------------+
| 2 | | | | // Content printed in white on blue
+------------+------------+------------+------------+
| 3 | | | |
+------------+------------+------------+------------+
| 4 | | | |
+------------+------------+------------+------------+
*/
?>
<?php
require_once 'tutorial_autoload.php';
$input = new ezcConsoleInput();
$helpOption = $input->registerOption( new ezcConsoleOption( 'h', 'help' ) );
$inputOption = $input->registerOption(
new ezcConsoleOption(
'i',
'input',
ezcConsoleInput::TYPE_STRING
)
);
$outputOption = $input->registerOption(
new ezcConsoleOption(
'o',
'output'
)
);
$outputOption->type = ezcConsoleInput::TYPE_STRING;
$inputOption->addDependency(
new ezcConsoleOptionRule( $outputOption )
);
$outputOption->addDependency(
new ezcConsoleOptionRule( $inputOption )
);
try
{
$input->process();
}
catch ( ezcConsoleOptionException $e )
{
die( $e->getMessage() );
}
if ( $helpOption->value === true )
{
echo $input->getSynopsis() . "\n";
foreach ( $input->getOptions() as $option )
{
echo "-{$option->short}/{$option->long}: {$option->shorthelp}\n";
}
}
elseif ( $outputOption->value !== false )
{
echo "Input: {$inputOption->value}, Output: {$outputOption->value}\n";
echo "Arguments: " . implode( ", ", $input->getArguments() ) . "\n";
}
?>
<?php
require_once "Base/src/base.php";
function __autoload( $className )
{
ezcBase::autoload( $className );
}
$out = new ezcConsoleOutput();
$opts = new ezcConsoleQuestionDialogOptions();
$opts->text = "How old are you?";
$opts->showResults = true;
$opts->validator = new ezcConsoleQuestionDialogTypeValidator(
ezcConsoleQuestionDialogTypeValidator::TYPE_INT
);
$dialog = new ezcConsoleQuestionDialog( $out, $opts );
if ( ( $res = ezcConsoleDialogViewer::displayDialog( $dialog ) ) < 8 )
{
echo "Sorry, I can not believe that you are $res years old!\n";
}
else
{
echo "Hey, you're still young! :)\n";
}
?>
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$menu = new ezcConsoleMenuDialog( $output );
$menu->options = new ezcConsoleMenuDialogOptions();
$menu->options->text = "Please choose a possibility:\n";
$menu->options->validator = new ezcConsoleMenuDialogDefaultValidator(
array(
"1" => "Perform some more actions",
"2" => "Perform another action",
"0" => "Quit",
),
"0"
);
while ( ( $choice = ezcConsoleDialogViewer::displayDialog( $menu ) ) != 0 )
{
switch ( $choice )
{
case 1:
echo "Performing some more actions...\n";
break;
case 2:
echo "Performing some other actions!\n";
break;
}
}
?>
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$output->formats->info->color = 'blue';
$output->formats->error->color = 'red';
$output->formats->error->style = array( 'bold' );
$output->formats->fatal->color = 'red';
$output->formats->fatal->style = array( 'bold', 'underlined' );
$output->formats->fatal->bgcolor = 'black';
$output->outputText( 'This is some standard text ' );
$output->outputText( 'including some error', 'error' );
$output->outputText( ' wrapped in standard text.' );
$output->outputText( "\n" );
$output->outputLine( 'This is a fatal error message.', 'fatal' );
$output->outputText( 'Test' );
?>
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$output->formats->info->color = 'blue';
$output->outputText( 'Test text in color blue', 'info' );
?>
<?php
require_once "Base/src/base.php";
function __autoload( $className )
{
ezcBase::autoload( $className );
}
$out = new ezcConsoleOutput();
$opts = new ezcConsoleMenuDialogOptions();
$opts->text = "Please choose a possibility:\n";
$opts->validator = new ezcConsoleMenuDialogDefaultValidator(
array(
"A" => "Selection A",
"B" => "Selection B",
"C" => "Selection C",
"D" => "Selection D",
"Z" => "Selection Z",
),
"Z"
);
$dialog = new ezcConsoleMenuDialog( $out, $opts );
$res = ezcConsoleDialogViewer::displayDialog( $dialog );
echo "User seletced $res\n";
?>
<?php
$dir = dirname( __FILE__ );
$dirParts = explode( DIRECTORY_SEPARATOR, $dir );
switch ( $dirParts[count( $dirParts ) - 3] )
{
case 'doc': require_once 'ezc/Base/base.php'; break; // pear
case 'trunk': require_once "$dir/../../Base/src/base.php"; break; // svn
default: require_once "$dir/../../Base/src/base.php"; break; // bundle
}
/**
* Autoload ezc classes
*
* @param string $className
*/
function __autoload( $className )
{
ezcBase::autoload( $className );
}
?>
<?php
/**
* Example for the usage of ezcConsoleStatusbar class.
*
* @package ConsoleTools
* @version 1.6.1
* @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
* @license http://ez.no/licenses/new_bsd New BSD License
*/
require_once 'Base/src/base.php';
/**
* Autoload ezc classes
*
* @param string $className
*/
function __autoload( $className )
{
ezcBase::autoload( $className );
}
$out = new ezcConsoleOutput();
// Create status bar itself
$status = new ezcConsoleStatusbar( $out );
// Perform actions
$i = 0;
while( $i++ < 20 )
{
// Do whatever you want to indicate progress for
usleep( mt_rand( 20000, 2000000 ) );
// Indicate success or failure
$status->add( (bool)mt_rand( 0, 1 ) );
}
$out->outputLine();
// Print statistics
$out->outputLine( $status->getSuccessCount() . ' operations succeeded, ' . $status->getFailureCount() . ' failed.' );
/*
OUTPUT:
+-++++-++++-++-+--+-
13 operations succeeded, 7 failed.
*/
?>
<?php
require_once "Base/src/base.php";
function __autoload( $className )
{
ezcBase::autoload( $className );
}
$out = new ezcConsoleOutput();
$opts = new ezcConsoleQuestionDialogOptions();
$opts->text = "Do you want to proceed?";
$opts->showResults = true;
$opts->validator = new ezcConsoleQuestionDialogCollectionValidator(
array( "y", "n" ),
"n",
ezcConsoleQuestionDialogCollectionValidator::CONVERT_LOWER
);
$dialog = new ezcConsoleQuestionDialog( $out, $opts );
echo "The user decided to " . ( ezcConsoleDialogViewer::displayDialog( $dialog ) === "n" ? "not " : "" ) . "proceed.\n";
?>
eZ Components - ConsoleTools
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. contents:: Table of Contents
Introduction
============
The ConsoleTools component provides several useful tools to build
applications that run on a computer console (sometimes also called shell or
command line). For example, eZ Publish includes several shell
scripts that perform tasks like clearing caches.
.. note::
From version 1.5.2 on, all necessary string operations in ConsoleTools are
performed using `ext/iconv`__. This makes the component binary safe and
allows you to use arbitrary unicode characters in your texts. Please make
sure to convert your text to UTF-8 before submitting it to a method in
ConsoleTools, if you use a different, non ASCII-compatible encoding.
.. __: http://php.net/iconv
Class overview
==============
The ConsoleTools component offers several (mostly independent) classes to
perform different tasks. The main classes are:
ezcConsoleOutput
ezcConsoleOutput is responsible for printing text to the console. It allows
you to print text in different colors with different background colors.
It can also apply other styling information to the text, making
it bold or underlined for example. It can automatically wrap text
after a certain number of characters are printed (keeping words
intact) and handle output of different verbosity levels. ATTENTION: Windows
does not support the styling of text.
ezcConsoleInput
Using this little tool, you can handle the options and arguments provided to
your shell application. It is capable of handling and validating three types of
option datatypes (string, int and none) and can handle optional and mandatory
options as well as rules to define relations between them. Rules can include
dependencies and exclusions between options.
ezcConsoleProgressbar
Most often you will use a console application in favor of a web application
when it comes to processing time-consuming tasks. To indicate the
current progress of a task, a kind of "status
indicator" will be used, which is most commonly a progress bar.
ezcConsoleProgressbar gives you an easy-to-use interface to display this.
It will keep track of re-drawing the bar as needed, showing current
and maximum values, as well as percentage completion. It is
fully configurable regarding its visual appearance.
ezcConsoleStatusbar
ezcConsoleStatusbar is the "little brother" of ezcConsoleProgressbar. It
also allows you to display the progress of a time-consuming action, but does
not use a fixed bar-like appearance. Instead, it indicates successful
and failed operations by displaying specific characters and keeps a
count of successes and failures. This allows you to indicate
the progress of a process where you don't initially know the number of
actions to be performed.
ezcConsoleProgressMonitor
Sometimes you need to display the progress of several actions and don't want
to use a progress bar to do so. In this case you need the status indicator.
It allows you to display a status entry for each action and generates the
percentage completion of the current step.
ezcConsoleTable
This class lets you easily create tables to be displayed on the
console. It has a very convenient interface to create a table and manage the
data it contains. It is highly configurable regarding the table's appearance
(for example, different color and style information for content
and borders on a per-cell basis, character selection for borders, variable
width of the table and so on). ezcConsoleTable will also take care of measuring the
best width for table columns (to make your content fit best), automatically
wrapping content and aligning the content in the cells as indicated.
ezcConsoleDialog
This interface provides a common API for user interaction elements. A console
dialog can request information from a user and react on this information
interactively. For you as a user of ezcConsoleDialog, a dialog is displayed
to the user and returns a result value to you, which was provided by the user
of your application in some way. Currently 2 implementations of
ezcConsoleDialog exist: ezcConsoleQuestionDialog is a dialog for asking a
simply question and retrieving the answer from the user of an application.
Instances of the ezcConsoleMenuDialog class display a menu to the user and
retrieves his choice of a menu item.
Usage
=====
Printing text to the console
----------------------------
As mentioned, the class ezcConsoleOutput is used to print text to the console.
Let's look at a basic example:
.. include:: tutorial_example_01_output_basic.php
:literal:
The ezcConsoleOutput object is simply instantiated. You can optionally submit
options and predefined formatting options to its constructor, but this can also
be done later.
In line 7, you can see how format is defined. Formats are created on the fly,
as soon as you access them (for reading or writing) through the $output->formats
attribute. There, we create a format called "info" and assign the color value
"blue" to it. This will make all text printed with this format blue. In line 9,
you can see how the format is applied to some text at printing time.
The second example shows some more advanced code:
.. include:: tutorial_example_02_output_advanced.php
:literal:
In this example, two more formats are defined: "error" and "fatal". These formats
have an additional style attribute set, which makes them both appear bold. The
"fatal" format will also underline the text and give it a black background
color.
The difference between ezcConsoleOutput->outputText() and
ezcConsoleOutput->outputLine() is that the latter automatically adds a
newline value to your text. The newline sequence used here is adjusted based on
the operating system. The use of ezcConsoleOutput->outputLine() is recommended
over the direct output of, for example, "\n".
If you leave the second parameter of ezcConsoleOutput::outputText() and
ezcConsoleOutput::outputLine() out, the "default" format is used. The default
is set to your console's default setting, but you can also change this as
for any other format you define. A third variant to format text is
ezcConsoleOutput->formatText(), which returns the formatted string instead of
printing it.
This example shows some of the options ezcConsoleOutput supports:
.. include:: tutorial_example_03_output_options.php
:literal:
autobreak
Will wrap lines automatically after the set amount of characters, keeping
word boundaries intact.
verbosityLevel
Allows you to specify a third parameter to ezcConsoleOutput->outputLine() and
ezcConsoleOutput->outputText() to indicate a verbosity level for when the text
should be printed. By setting the "verbosityLevel" option for
ezcConsoleOutput, you define which texts will and will not be printed.
In our example, the call on line 23 would not print out text with the
"verbosityLevel" option set to 3, but the call on line 25 would.
The last example shows how to change the target of a format, which allows you
to print text e.g. to STDERR.
.. include:: tutorial_example_output_targets.php
:literal:
The error message 'Unable to connect to database' will be printed in bold, with
a red foreground color to STDOUT. The default target is
ezcConsoleOutput::TARGET_OUTPUT, which prints to STDOUT and has standar output
buffering in place. If you want to switch out the standard output bufferung,
use ezcConsoleOutput::TARGET_STDOUT.
Although this feature was originally not designed for that purpose, you can
also use any other arbitrary PHP stream definition as a target. For example
'file:///var/log/my.log' to get the messages redirected to a log file instead
of displaying them.
Mastering options and arguments
-------------------------------
Below is a simple example for ezcConsoleInput:
.. include:: tutorial_example_04_input_basic.php
:literal:
After instantiating a new ezcConsoleInput object to handle the options, an
option is registered on lines 7-12. This option will be available as "-h" and
"--help". The ezcConsoleInput->process() call makes ezcConsoleInput respond to the
options submitted by the user. If any error occurs with the submitted user
data, the method will throw an exception of type ezcConsoleOptionException. By
default, all options are registered with the value type
ezcConsoleInput::TYPE_NONE, which indicates that they don't expect a value
from the user. If a value is submitted anyway, ezcConsoleInput->process() will
throw a ezcConsoleOptionTypeViolationException.
On line 23, a check is performed to see whether an option was submitted. If an option was not
submitted, its $value property will contain bool *false*. Depending on the $type
set, it can contain different value types if it was submitted. If you use the
(not shown here) ezcConsoleOption->$multiple property, the value will be an array
containing the specified value types.
The next example is more advanced:
.. include:: tutorial_example_05_input_advanced.php
:literal:
Two options are registered here: "-i" / "--input" and "-o" / "--output". For the
first one, additional properties for the ezcConsoleOption object are submitted
through the constructor. For the second ezcConsoleOption object, you see how to
provide additional properties after construction. We change the type of both
options to expect a string value from the user (lines 13 and 20).
In lines 25 and 28 we make both parameters depend on each other. If one of them
is submitted without the other, ezcConsoleInput->process() will throw an
ezcConsoleOptionDependencyViolationException. Aside from dependency rules, you can
also define exclusion rules using ezcConsoleOption->addExclusion().
On line 43, the method ezcConsoleInput->getSynopsis() is used to retrieve a
synopsis string for the program. The synopsis for our example would look like
this: ::
$ ./tutorial_example_05_input_advanced.php [-h] [-i <string> [-o <string>] ] [[--] <args>]
The synopsis will indicate the option value types, whether they are optional, the
inter-option dependencies and default values (if set). On line 46, the property
ezcConsoleOption->$shorthelp is accessed, where you can store some short help
information. It has a reasonable default value set.
On line 49, the submission of the "-o" option is checked. Because this has a
dependency on the "-i" option, a check for that is not necessary. Line 52
shows how you can access the arguments submitted to the program.
ezcConsoleInput->getArguments() always returns an array (which is empty if no
arguments are submitted). A more advanced way of handling arguments is
explained further below.
Here is an example of how the defined program would be called: ::
$ ./tutorial_example_05_input_advanced.php -i /var/www -o /tmp foo bar
The program would respond by printing the following: ::
Input: /var/www, Output: /tmp
Arguments: foo, bar
As you can see, this example does not define, which arguments are expected and
therefore, the program simply accepts any number of arguments and provides them
through the ezcConsoleInput->getArguments() method. The following example
shows, how specific arguments can be defined:
.. include:: tutorial_example_12_input_arguments.php
:literal:
As seen before, a help option is registered. In addition, 3 arguments are
registered: The first one with the name "source" is a standard argument. It is
mandatory for the user to submit a value here. The second argument,
"destination" is optional and a default value is assigned, which will be used,
if the user does not provide a value for it.
The third one ("iterations") is not of type string, but an integer. Because the
second argument is optional, this third one is automatically optional, too.
Since no default value is assigned, it will be null, if the user does not
submit it. If a value is provided, it must be an integer.
Argument definitions are processed as usual inside the
ezcConsoleInput->process() method, but will throw an
ezcConsoleArgumentException if something goes wrong. If desired, exceptions
about options and arguments can be caught together using ezcConsoleException or
be handled on their own.
The value of an argument can be fetched from its definition, using its value
property. As can be seen at the very end of the example, for reading purpose,
arguments can be accessed by their name. This does not work for writing
purpose, since a specific order must be given there.
If the --help option is set, mandatory arguments don't need to be submitted and
are silently ignored. The help text generated by ezcConsoleInput for this
example looks like this: ::
Usage: $ tutorial_example_12_input_arguments.php [-h] [--] <string:source> [<string:destination>] [<int:iterations>]
A simple text program
-h / --help No help available.
Arguments:
<string:source> The source directory.
<string:destination> No help available.
<int:iterations> Number of iterations.
For further information, please refer to the API documentation of
ezcConsoleInput.
Progress indication
-------------------
This example defines a simple progress bar:
.. include:: tutorial_example_06_progressbar_basic.php
:literal:
The created progressbar will count to a maximum value of 15, submitted to
ezcConsoleProgressbar->__construct() in line 7. ezcConsoleProgressbar utilizes
ezcConsoleOutput to print the generated progress bar. The call to
ezcConsoleProgressbar->advance() pushes the progress bar one step further on each
call and redraws it (line 11). Calling ezcConsoleProgressbar->finish() will set
the progress bar to 100% immediately.
The progress bar generated by the example will look like this:
.. image:: img/consoletools_tutorial_example_06.png
The next example performs more customization on the progress bar appearance:
.. include:: tutorial_example_07_progressbar_advanced.php
:literal:
The defined options array demonstrates only a small subset of options. For
detailed information, see the API documentation on
ezcConsoleProgressbarOptions. The "emptyChar" value defines the character to
prefill the bar, the "barChar" option defines the character to fill the bar
with when calling ezcConsoleProgressbar->advance().
Using the "formatString" option, you define the appearance of the whole bar.
Here the substitution of several placeholders (like "%fraction%" and "%bar%")
is permitted. "formatString" must contain the "%bar%" placeholder, while all
other values are optional. Any other printable character is permitted.
Formatting options are allowed in the "formatString" option, but
not in any other option. "redrawFrequency" defines how often the
progressbar will be redrawn. In the example this will be every 50th call to
ezcConsoleProgressbar->advance().
The resulting progress bar looks like this:
.. image:: img/consoletools_tutorial_example_07.png
With ezcConsoleStatusbar, you can indicate the progress of a time-consuming
action in a simpler way. Here is an example:
.. include:: tutorial_example_08_statusbar.php
:literal:
This variant of indicating progress only displays success or failure indicators
for an action and allows you to run any number of actions, without specifying
in advance how many you will perform. The "successChar" and "failureChar" options
indicate which string to print on a successful or failed action. Lines 11 and
12 format these strings.
Indicating a status is done using ezcConsoleStatusbar->add(), which expects
*true* for a succeeded action and *false* for a failed one (line 20). You can
access the number of successes and failures through
ezcConsoleStatusbar->getSuccessCount() and
ezcConsoleStatusbar->getFailureCount(). To make ezcConsoleStatusbar
wrap a line after a certain amount of statuses, you can use
ezcConsoleOutput->$autobreak.
Here the result of the example:
.. image:: img/consoletools_tutorial_example_08.png
Finally, ezcConsoleProgressMonitor can indicate progress, but does not use a
bar-like interface. It simply prints status information about each action you
perform and shows the current progress as a percentage value in relation to the
number of actions you plan to perform overall.
.. include:: tutorial_example_11_progressmonitor.php
:literal:
Line 7 creates a new status indicator, which will iterate over 7 actions.
Inside the while loop, we simulate some actions. The
call to $status->addEntry() adds a status entry and causes the indicator to
print the entry. Every entry consists of a tag (first parameter) and a message.
The result of the example is as follows:
::
14.3% ACTION Performed action #1.
28.6% ACTION Performed action #2.
42.9% ACTION Performed action #3.
57.1% ACTION Performed action #4.
71.4% ACTION Performed action #5.
85.7% ACTION Performed action #6.
100.0% ACTION Performed action #7.
More information on these classes can be found in the API documentation of
ezcConsoleProgressbar, ezcConsoleStatusbar and ezcConsoleProgressMonitor.
Large data served in a table
----------------------------
This is the result of a table generated by ezcConsoleTable:
.. image:: img/consoletools_tutorial_example_09.png
Here is its corresponding source code:
.. include:: tutorial_example_09_table_basic.php
:literal:
ezcConsoleTable (like ezcConsoleStatusbar and ezcConsoleProgressbar) uses the
ezcConsoleOutput class to print to the console. To create a table, you just
need to submit the maximum width of the table to its constructor:
ezcConsoleTable->__construct(). Options for table formatting are inherited
from the table itself to the table rows and from there to the table cells.
On each inheritance level, options can be overridden individually. The
"defaultBorderFormat" option sets the global format value for all borders (line
24). This is overridden in line 26 for the first row of the table.
Table rows are accessed like an array in PHP (this is achieved by
implementing the ArrayAccess_ interface from SPL_).
ezcConsoleTable implements the Iterator interface (SPL_, too) to allow
iteration over table rows using foreach. Each table row is represented by an
object of type ezcConsoleTableRow, which also implements the ArrayAccess_ and
Iterator interfaces to access cells contained in the rows in the same way. Each
of the named classes allows the access of its properties as usual, in addition
to access to its contained objects through the array interface.
ezcConsoleTableRow and ezcConsoleTableCell have a $format setting to define the
format of the contained text. All cells (as described above) will inherit the
setting of their parent ezcConsoleTableRow, as long as this has not been
explicitly overridden. The same applies to ezcConsoleTableRow->$align and
ezcConsoleTableCell->$align. Possible align values are:
- ezcConsoleTable::ALIGN_DEFAULT (inherit from parent)
- ezcConsoleTable::ALIGN_LEFT
- ezcConsoleTable::ALIGN_RIGHT
- ezcConsoleTable::ALIGN_CENTER
The content of a cell is stored in the ezcConsoleTableCell->$content property
(line 34). The usage of formatted text in a cell is possible, but not recommended.
If you want to define the format of cell content, use the
ezcConsoleTableCell->$format property.
.. _SPL: http://php.net/spl
.. _ArrayAccess: http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html
Below is a more advanced (but in a way useless) example to show the handling of
tables:
.. include:: tutorial_example_10_table_advanced.php
:literal:
The "corner", "lineHorizontal" and "lineVertical" options define which
characters to use for the borders of the table. These options must be
exactly one character long and cannot contain formatting information. To style the
borders, use the ezcConsoleTable->$defaultBorderFormat and
ezcConsoleTableRow->$borderFormat properties.
The random format and alignment options selected above create the following
table:
.. image:: img/consoletools_tutorial_example_10.png
More information on the handling of tables on the shell can be found in the API
documentation of ezcConsoleTable, ezcConsoleTableRow and ezcConsoleTableCell.
Interacting with the user
-------------------------
Implementations of the interface ezcConsoleDialog are generic building blocks,
which allow to interact with the user of a shell application using STDIN. A
dialog is initialized, displayed and will return a value provided by the user.
What exactly happens inside a specific dialog may vary. Commonly, the dialog
validates and possibly manipulates the provided value before returning it.
The most basic dialog is the ezcConsoleQuestionDialog, which prints out some
text and retrieves a single value back.
.. include:: tutorial_example_13_dialog_question.php
:literal:
Every dialog expects an instance of ezcConsoleOutput which is used to display
it. The question dialog here will display the text "Do you want to proceed?"
and expects an answer from the user. The $showResults option indicates, that
the possible values the user may provide will be indicated, as well as the
default value, if one is set.
The mechanism for validating the answer is defined by an instance of
ezcConsoleQuestionDialogValidator. In the example, a collection validator is
used, which defines a collection of valid values. Beside that, it performs a
case conversion on the user provided result before validating it, if desired.
Displaying a dialog can either be done directly, by calling
ezcConsoleDialog->display(), or the more convenient way, shown in the example.
The ezcConsoleDialogViewer::displayDialog() method displays the dialog in a
loop, until the user provided a valid value, so that the program can rely on
this. In the example, the user is asked after every performed action, if he
still wants to proceed. If the answer is "n" or "N", the program stops.
An example run of this application could look like this: ::
Some action performed...
Do you want to proceed? (y/n) [y] y
Some action performed...
Do you want to proceed? (y/n) [y]
Some action performed...
Do you want to proceed? (y/n) [y] n
Goodbye!
A very similar yes/no question can be created through convenience method very
easily:
.. include:: tutorial_example_14_dialog_yesnoquestion.php
:literal:
The created yes/no question dialog contains a custom question and defaults to
"y", if nothing is selected. In contrast to the last example, the dialog
created here also accepts "yes" and "no" as answers. Both phrases can be used
in any typing, e.g. like "yEs" or "NO". This is made possibly by the
ezcConsoleQuestionDialogMappingValidator, which extends
ezcConsoleQuestionDialogCollectionValidator. The mapping validator allows to
define an arbitrary mapping between the user typed answers and expected ones.
Therefore the dialog still only returns either "y" or "n".
The second dialog type, provided with ConsoleTools, is the
ezcConsoleMenuDialog. Similar to the ezcConsoleQuestionDialog, it displays a
list of menu items to the user and requires him to choose one of these. An
example for this class looks like this:
.. include:: tutorial_example_15_dialog_menu.php
:literal:
Again the dialog is instantiated and some options are tweaked to get the
desired behaviour. The validator in this case receives an array of possible
menu items, while the key represents the identifier and the value contains the
text to be displayed for the item. The second argument is the default value,
chosen if the user simply presses <return>.
An example run of this program could look like this: ::
Please choose a possibility:
1) Perform some more actions
2) Perform another action
0) Quit
Select: [0] 1
Performing some more actions...
Please choose a possibility:
1) Perform some more actions
2) Perform another action
0) Quit
Select: [0] 2
Performing some other actions!
Please choose a possibility:
1) Perform some more actions
2) Perform another action
0) Quit
Select: [0]
The character used to divide the identifier and text, as well as the text
indicating that a selection must be done, can be tweaked, too.
Further information about dialogs can be found in the API documentation of
ezcConsoleDialog, ezcConsoleQuestionDialog and ezcConsoleMenuDialog.
..
Local Variables:
mode: rst
fill-column: 79
End:
vim: et syn=rst tw=79
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$bar = new ezcConsoleProgressbar( $output, 15 );
for ( $i = 0; $i < 15; $i++ )
{
$bar->advance();
usleep( mt_rand( 2000, 200000 ) );
}
$bar->finish();
$output->outputLine();
?>
<?php
/**
* Example for the usage of ezcConsoleProgressMonitor class.
*
* @package ConsoleTools
* @version 1.6.1
* @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
* @license http://ez.no/licenses/new_bsd New BSD License
*/
require_once 'Base/src/base.php';
/**
* Autoload ezc classes
*
* @param string $className
*/
function __autoload( $className )
{
ezcBase::autoload( $className );
}
$out = new ezcConsoleOutput();
// Create a progress monitor
$status = new ezcConsoleProgressMonitor( $out, 7 );
// Perform actions
$i = 0;
while( $i++ < 7 )
{
// Do whatever you want to indicate progress for
usleep( mt_rand( 20000, 2000000 ) );
// Advance the statusbar by one step
$status->addEntry( 'ACTION', "Performed action #{$i}." );
}
$out->outputLine();
/*
OUTPUT:
14.3% ACTION Performed action #1.
28.6% ACTION Performed action #2.
42.9% ACTION Performed action #3.
57.1% ACTION Performed action #4.
71.4% ACTION Performed action #5.
85.7% ACTION Performed action #6.
100.0% ACTION Performed action #7.
*/
?>
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$output->formats->blue->color = 'blue';
$output->formats->blue->style = array( 'bold' );
$output->formats->red->color = 'red';
$output->formats->red->style = array( 'bold' );
$output->formats->green->color = 'green';
$output->formats->green->style = array( 'bold' );
$colors = array( 'red', 'blue', 'green' );
$aligns = array( ezcConsoleTable::ALIGN_LEFT, ezcConsoleTable::ALIGN_CENTER, ezcConsoleTable::ALIGN_RIGHT );
$table = new ezcConsoleTable( $output, 78 );
$table->options->corner = ' ';
$table->options->lineHorizontal = ' ';
$table->options->lineVertical = ' ';
$table->options->widthType = ezcConsoleTable::WIDTH_FIXED;
for ( $i = 0; $i < 10; $i++ )
{
for ( $j = 0; $j < 10; $j++ )
{
$table[$i][$j]->content = '*';
$table[$i][$j]->format = $colors[array_rand( $colors )];
$table[$i][$j]->align = $aligns[array_rand( $aligns )];
}
}
$table->outputTable();
$output->outputLine();
?>
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$output->formats->bar->color = 'blue';
$output->formats->bar->style = array( 'bold' );
$options = array(
'emptyChar' => ' ',
'barChar' => '-',
'formatString' => '%fraction%% <' . $output->formatText( '%bar%', 'bar' ) . '> Uploaded %act% / %max% kb',
'redrawFrequency' => 50,
);
$bar = new ezcConsoleProgressbar( $output, 1024, $options );
for ( $i = 0; $i < 1024; $i++ )
{
$bar->advance();
usleep( mt_rand( 200, 2000 ) );
}
$bar->finish();
$output->outputLine();
?>
<?php
require_once 'tutorial_autoload.php';
$input = new ezcConsoleInput();
$helpOption = $input->registerOption(
new ezcConsoleOption(
'h',
'help'
)
);
try
{
$input->process();
}
catch ( ezcConsoleOptionException $e )
{
die( $e->getMessage() );
}
if ( $helpOption->value !== false )
{
echo "Help requested.";
}
else
{
echo "No help requested.";
}
?>
<?php
require_once "Base/src/base.php";
function __autoload( $className )
{
ezcBase::autoload( $className );
}
$out = new ezcConsoleOutput();
$dialog = ezcConsoleQuestionDialog::YesNoQuestion( $out, "Is the answer to everything 42?", "y" );
if ( ( $res = ezcConsoleDialogViewer::displayDialog( $dialog ) ) === "y" )
{
echo "You are so right! Don't forget your towel! :)\n";
}
else
{
echo "You should better read some Douglas Adams!\n";
}
?>
<?php
require_once 'tutorial_autoload.php';
$output = new ezcConsoleOutput();
$output->formats->error->color = 'red';
$output->formats->error->style = array( 'bold' );
$output->formats->error->target = ezcConsoleOutput::TARGET_STDERR;
$output->outputLine( 'Unable to connect to database', 'error' );
?>
�PNG
IHDR U � i�� bKGD � � ����� pHYs �� tIME� 2,��N
�IDATx�흿n�8�7�W�0�.\�᮸'I��s�¥�p���=��!g��Q��-E͐?�PZ����ǿ'