Compare commits
1 commit
main
...
fix/rankin
Author | SHA1 | Date | |
---|---|---|---|
bc2d1e27ad |
1
.gitattributes
vendored
|
@ -1 +0,0 @@
|
|||
src/includes/config.php merge=ours
|
2
.gitignore
vendored
|
@ -1,3 +1,3 @@
|
|||
src/templates_c
|
||||
src/item_images
|
||||
**/.*.swp
|
||||
|
||||
|
|
39
README.md
|
@ -1,38 +1 @@
|
|||
# PHP Gift Wishlist
|
||||
|
||||
The PHP Gift Wishlist is a web-enabled gift registry intended for use among
|
||||
a circle of family members or friends.
|
||||
|
||||
This project is based on [phpgiftreg](https://github.com/generalpf/phpgiftreg).
|
||||
I have forked Ryan's repository and made many changes. Thank you, Ryan, for all
|
||||
of your hard work!
|
||||
|
||||
It is intended to fill the following purposes:
|
||||
|
||||
* Permit the long-term storage of a list of items one desires, along with its price, where it can be bought, and (optionally) a URL where it can be
|
||||
viewed.
|
||||
* Enabled items to be "locked" by one shopper so that the same item is not bought by someone else.
|
||||
|
||||
Its features include:
|
||||
|
||||
* A single unifying view of items on your own list and people whose lists you can view.
|
||||
* A now-optional request/permit system by which you can control who can see your list.
|
||||
* A "checkin/checkout" system which allows you to reserve items on someone's list.
|
||||
* An in-system messaging system by which users can be informed of item deletions or custom announcements.
|
||||
* New users can request accounts. Optionally, administrators will be informed about the request, and they can then approve or reject the request. Either way, the user will be informed by e-mail.
|
||||
* A site-customizable ranking system for items.
|
||||
* An events system for users to add significant (read: gift-bearing) events which will show up on others' displays when the event nears.
|
||||
|
||||
## Installing
|
||||
|
||||
Read [INSTALL](src/INSTALL) for installation instructions.
|
||||
|
||||
If you have any questions, comments, feature requests, or patches, feel free to e-mail me.
|
||||
|
||||
## License
|
||||
|
||||
phpgiftreg is licensed by the GPL. For more information on the GPL, visit http://www.gnu.org
|
||||
|
||||
Copyright 2024 Michael Erdely <mike@erdelynet.com>
|
||||
|
||||
Copyright 2022 Ryan Walberg <generalpf@gmail.com> [@GeneralPeeEff](https://twitter.com/GeneralPeeEff)
|
||||
The README.md for the application is in [src](src/README.md).
|
||||
|
|
|
@ -20,7 +20,7 @@ $opt = $smarty->opt();
|
|||
|
||||
session_start();
|
||||
if (!isset($_SESSION["userid"])) {
|
||||
header("Location: " . getFullPath("login.php") . "?from=admin.php");
|
||||
header("Location: " . getFullPath("login.php"));
|
||||
exit;
|
||||
}
|
||||
else if ($_SESSION["admin"] != 1) {
|
||||
|
@ -31,80 +31,54 @@ else {
|
|||
$userid = $_SESSION["userid"];
|
||||
}
|
||||
|
||||
if (isset($_GET["familyid"])) {
|
||||
$familyid = filter_var(trim($_GET["familyid"]), FILTER_SANITIZE_NUMBER_INT);
|
||||
|
||||
if (filter_var($familyid, FILTER_SANITIZE_NUMBER_INT) === false || $familyid == "" || !is_numeric($familyid) || $familyid < 0) {
|
||||
die("Invalid familyid ({$_GET["familyid"]})");
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET["userid"])) {
|
||||
$userid = filter_var(trim($_GET["userid"]), FILTER_SANITIZE_NUMBER_INT);
|
||||
|
||||
if (filter_var($userid, FILTER_SANITIZE_NUMBER_INT) === false || $userid == "" || !is_numeric($userid) || $userid < 0) {
|
||||
die("Invalid userid ({$_GET["userid"]})");
|
||||
}
|
||||
}
|
||||
|
||||
$action = $_GET["action"];
|
||||
if ($action == "approve") {
|
||||
$pwd = generatePassword($opt);
|
||||
if ($familyid != "") {
|
||||
if ($_GET["familyid"] != "") {
|
||||
$stmt = $smarty->dbh()->prepare("INSERT INTO {$opt["table_prefix"]}memberships(userid,familyid) VALUES(?, ?)");
|
||||
$stmt->bindValue(1, (int) $userid, PDO::PARAM_INT);
|
||||
$stmt->bindValue(2, (int) $familyid, PDO::PARAM_INT);
|
||||
$stmt->bindValue(1, (int) $_GET["userid"], PDO::PARAM_INT);
|
||||
$stmt->bindValue(2, (int) $_GET["familyid"], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
}
|
||||
$stmt = $smarty->dbh()->prepare("UPDATE {$opt["table_prefix"]}users SET approved = 1, password = {$opt["password_hasher"]}(?) WHERE userid = ?");
|
||||
$stmt->bindParam(1, $pwd, PDO::PARAM_STR);
|
||||
$stmt->bindValue(2, (int) $userid, PDO::PARAM_INT);
|
||||
$stmt->bindParam(1, $pwd, PDO::PARAM_INT);
|
||||
$stmt->bindValue(2, (int) $_GET["userid"], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
// send the e-mails
|
||||
$stmt = $smarty->dbh()->prepare("SELECT username, email FROM {$opt["table_prefix"]}users WHERE userid = ?");
|
||||
$stmt->bindValue(1, (int) $userid, PDO::PARAM_INT);
|
||||
$stmt->bindValue(1, (int) $_GET["userid"], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
if ($row = $stmt->fetch()) {
|
||||
mail(
|
||||
$row["email"],
|
||||
"Gift Registry application approved",
|
||||
"Your Gift Registry application was approved.\r\n" .
|
||||
"Your username is {$row["username"]} and your password is '$pwd'.\r\n" .
|
||||
"Log in to {$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}/ and change your password under " .
|
||||
"'Update Profile' as soon as possible:\r\n" .
|
||||
" {$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}/profile.php\r\n" .
|
||||
"\r\n" .
|
||||
"There is help and a browser bookmarklet at {$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}/help.php\r\n" .
|
||||
"\r\n" .
|
||||
"Once you've logged in, you can see the people you can shop for under 'Available People To Shopping For'. " .
|
||||
"Click on the icon next to each person you want to shop for to see their lists.\r\n" .
|
||||
"\r\n" .
|
||||
"If you have any questions or problems, email {$opt['email_from']}.\r\n",
|
||||
"Your Gift Registry application was approved by " . $_SESSION["fullname"] . ".\r\n" .
|
||||
"Your username is " . $row["username"] . " and your password is $pwd.",
|
||||
"From: {$opt["email_from"]}\r\nReply-To: {$opt["email_reply_to"]}\r\nX-Mailer: {$opt["email_xmailer"]}\r\n"
|
||||
) or die("Mail not accepted for " . $row["email"]);
|
||||
) or die("Mail not accepted for " . $row["email"]);
|
||||
}
|
||||
header("Location: " . getFullPath("families.php"));
|
||||
header("Location: " . getFullPath("index.php"));
|
||||
exit;
|
||||
}
|
||||
else if ($action == "reject") {
|
||||
// send the e-mails
|
||||
$stmt = $smarty->dbh()->prepare("SELECT email FROM {$opt["table_prefix"]}users WHERE userid = ?");
|
||||
$stmt->bindValue(1, (int) $userid, PDO::PARAM_INT);
|
||||
$stmt->bindValue(1, (int) $_GET["userid"], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
if ($row = $stmt->fetch()) {
|
||||
mail(
|
||||
$row["email"],
|
||||
"Gift Registry application denied",
|
||||
"Your Gift Registry application was denied.",
|
||||
"Your Gift Registry application was denied by " . $_SESSION["fullname"] . ".",
|
||||
"From: {$opt["email_from"]}\r\nReply-To: {$opt["email_reply_to"]}\r\nX-Mailer: {$opt["email_xmailer"]}\r\n"
|
||||
) or die("Mail not accepted for " . $row["email"]);
|
||||
) or die("Mail not accepted for " . $row["email"]);
|
||||
}
|
||||
|
||||
$stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}users WHERE userid = ?");
|
||||
$stmt->bindValue(1, (int) $userid, PDO::PARAM_INT);
|
||||
$stmt->bindValue(1, (int) $_GET["userid"], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
header("Location: " . getFullPath("index.php"));
|
||||
exit;
|
||||
}
|
||||
|
|
1088
src/bootstrap/css/bootstrap-responsive.css
vendored
Normal file
9
src/bootstrap/css/bootstrap-responsive.min.css
vendored
Normal file
6858
src/bootstrap/css/bootstrap.css
vendored
Normal file
9
src/bootstrap/css/bootstrap.min.css
vendored
Normal file
605
src/bootstrap/css/bootswatch.less
Normal file
|
@ -0,0 +1,605 @@
|
|||
// Flatness by Jenil (www.jgog.in)
|
||||
// Bootswatch 2.3.2
|
||||
// -----------------------------------------------------
|
||||
|
||||
|
||||
// TYPOGRAPHY
|
||||
// --------------------------------------------------
|
||||
|
||||
@import url("http://fonts.googleapis.com/css?family=Lato:400,700,900,400italic");
|
||||
|
||||
h1 {
|
||||
font-size: 48px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 36px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
// SCAFFOLDING
|
||||
// --------------------------------------------------
|
||||
|
||||
.page-header {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
|
||||
// NAVBAR
|
||||
// --------------------------------------------------
|
||||
|
||||
.navbar {
|
||||
|
||||
.brand {
|
||||
|
||||
text-shadow: none;
|
||||
|
||||
&:hover {
|
||||
color: @linkColorHover;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-inner {
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
.nav > li > a {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.nav > .active > a,
|
||||
.nav > .active > a:hover,
|
||||
.nav > .active > a:focus {
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
.navbar-search .search-query {
|
||||
border: none;
|
||||
.box-shadow(none);
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.btn-navbar {
|
||||
background-image: none;
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
.btn, .btn-group {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
&-inverse {
|
||||
|
||||
.brand:hover {
|
||||
color: @blueDark;
|
||||
}
|
||||
|
||||
.navbar-search .search-query {
|
||||
border-color: transparent;
|
||||
.box-shadow(none);
|
||||
line-height: normal;
|
||||
color: @textColor;
|
||||
|
||||
&:focus {
|
||||
padding: 4px 14px;
|
||||
color: @textColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.subnav {
|
||||
|
||||
border-color: transparent;
|
||||
background-image: none;
|
||||
background-color: @grayLighter;
|
||||
.box-shadow(none);
|
||||
|
||||
&-fixed {
|
||||
top: @navbarHeight;
|
||||
}
|
||||
|
||||
.nav > li > a {
|
||||
border-color: transparent;
|
||||
.box-shadow(none);
|
||||
color: @textColor;
|
||||
}
|
||||
|
||||
.nav > .active > a,
|
||||
.nav > .active > a:hover {
|
||||
border-color: transparent;
|
||||
background-color: darken(@grayLighter, 10%);
|
||||
.box-shadow(none);
|
||||
color: @textColor;
|
||||
}
|
||||
}
|
||||
|
||||
// NAVIGATION
|
||||
// --------------------------------------------------
|
||||
|
||||
.nav-list {
|
||||
|
||||
& > li > a,
|
||||
& > .active > a,
|
||||
.nav-header {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.divider {
|
||||
background: none;
|
||||
border-bottom: 2px solid @dropdownDividerBottom;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-pills {
|
||||
|
||||
.open .dropdown-toggle {
|
||||
background-color: @blueDark;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination {
|
||||
|
||||
ul {
|
||||
|
||||
.box-shadow(none);
|
||||
|
||||
& > li > a {
|
||||
background-color: @green;
|
||||
border-color: transparent;
|
||||
color: @white;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten(@green, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
& > .active > a,
|
||||
& > .active > a:hover {
|
||||
background-color: @paginationActiveBackground;
|
||||
color: @textColor;
|
||||
}
|
||||
|
||||
& > .disabled > a,
|
||||
& > .disabled > a:hover {
|
||||
background-color: lighten(@green, 10%);
|
||||
color: @white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pager {
|
||||
|
||||
li > a,
|
||||
li > span {
|
||||
background-color: @green;
|
||||
border: none;
|
||||
color: @white;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten(@green, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.disabled > a,
|
||||
.disabled > span,
|
||||
.disabled > a:hover,
|
||||
.disabled > span:hover {
|
||||
background-color: lighten(@green, 10%);
|
||||
color: @white;
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb {
|
||||
|
||||
& > li {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
// BUTTONS
|
||||
// --------------------------------------------------
|
||||
|
||||
.btn {
|
||||
padding: 9px 20px;
|
||||
border: none;
|
||||
background-image: none;
|
||||
color: @white;
|
||||
text-decoration: none;
|
||||
text-shadow: none;
|
||||
.box-shadow(none);
|
||||
-webkit-transition: 0.25s;
|
||||
-moz-transition: 0.25s;
|
||||
transition: 0.25s;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: white;
|
||||
-webkit-transition: 0.25s;
|
||||
-moz-transition: 0.25s;
|
||||
transition: 0.25s;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.active {
|
||||
.box-shadow(none);
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&[disabled] {
|
||||
color: white;
|
||||
}
|
||||
|
||||
&-large {
|
||||
padding: @paddingLarge;
|
||||
}
|
||||
|
||||
&-small {
|
||||
padding: @paddingSmall;
|
||||
}
|
||||
|
||||
&-mini {
|
||||
padding: @paddingMini;
|
||||
}
|
||||
}
|
||||
|
||||
// TABLES
|
||||
// -----------------------------------------------------
|
||||
|
||||
.table tbody tr {
|
||||
&.success > td,
|
||||
&.error > td,
|
||||
&.warning > td,
|
||||
&.info > td {
|
||||
color: @white;
|
||||
}
|
||||
}
|
||||
|
||||
// FORMS
|
||||
// --------------------------------------------------
|
||||
|
||||
textarea,
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="datetime"],
|
||||
input[type="datetime-local"],
|
||||
input[type="date"],
|
||||
input[type="month"],
|
||||
input[type="time"],
|
||||
input[type="week"],
|
||||
input[type="number"],
|
||||
input[type="email"],
|
||||
input[type="url"],
|
||||
input[type="search"],
|
||||
input[type="tel"],
|
||||
input[type="color"],
|
||||
.uneditable-input {
|
||||
padding: 7px 6px;
|
||||
border: 2px solid #dce4ec;
|
||||
text-indent: 1px;
|
||||
.border-radius(@inputBorderRadius);
|
||||
.box-shadow(none);
|
||||
.placeholder(#acb6c0);
|
||||
|
||||
&:focus {
|
||||
border-color: #1abc9c;
|
||||
.box-shadow(none);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.input-prepend {
|
||||
|
||||
.add-on:first-child,
|
||||
.btn:first-child {
|
||||
.border-radius(@inputBorderRadius 0 0 @inputBorderRadius);
|
||||
}
|
||||
}
|
||||
|
||||
.input-append {
|
||||
|
||||
input,
|
||||
select,
|
||||
.uneditable-input {
|
||||
|
||||
.border-radius(@inputBorderRadius 0 0 @inputBorderRadius);
|
||||
|
||||
+ .btn-group .btn:last-child {
|
||||
.border-radius(0 @inputBorderRadius @inputBorderRadius 0);
|
||||
}
|
||||
}
|
||||
|
||||
.add-on:last-child,
|
||||
.btn:last-child,
|
||||
.btn-group:last-child > .dropdown-toggle {
|
||||
.border-radius(0 @inputBorderRadius @inputBorderRadius 0);
|
||||
}
|
||||
}
|
||||
|
||||
.input-prepend,
|
||||
.input-append {
|
||||
|
||||
input,
|
||||
select,
|
||||
.uneditable-input {
|
||||
.border-radius(0);
|
||||
+ .btn-group .btn {
|
||||
.border-radius(0 @inputBorderRadius @inputBorderRadius 0);
|
||||
}
|
||||
}
|
||||
|
||||
.add-on:first-child,
|
||||
.btn:first-child {
|
||||
.border-radius(@inputBorderRadius 0 0 @inputBorderRadius);
|
||||
}
|
||||
|
||||
.add-on:last-child,
|
||||
.btn:last-child {
|
||||
.border-radius(0 @inputBorderRadius @inputBorderRadius 0);
|
||||
}
|
||||
}
|
||||
|
||||
.input-append,
|
||||
.input-prepend {
|
||||
|
||||
.add-on {
|
||||
padding: 9px 5px;
|
||||
text-shadow: none;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.control-group.error,
|
||||
.control-group.error input:focus,
|
||||
.control-group.error textarea:focus {
|
||||
border-color: #e74c3c;
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
.control-group.success,
|
||||
.control-group.success input:focus,
|
||||
.control-group.success textarea:focus {
|
||||
border-color: #2ecc71;
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
.control-group.warning,
|
||||
.control-group.warning input:focus,
|
||||
.control-group.warning textarea:focus {
|
||||
border-color: #f1c40f;
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
.control-group.info,
|
||||
.control-group.info input:focus,
|
||||
.control-group.info textarea:focus {
|
||||
border-color: #3498db;
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
input[disabled],
|
||||
input[readonly],
|
||||
textarea[disabled],
|
||||
textarea[readonly] {
|
||||
background-color: #eaeded;
|
||||
border-color: transparent;
|
||||
color: #cad2d3;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
input[type="file"]{
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
legend {
|
||||
border-bottom: none;
|
||||
color: @textColor;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
border-top: none;
|
||||
.border-radius(@baseBorderRadius);
|
||||
background-color: darken(@grayLighter, 5%);
|
||||
}
|
||||
|
||||
// DROPDOWNS
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
// ALERTS, LABELS, BADGES
|
||||
// --------------------------------------------------
|
||||
|
||||
.alert {
|
||||
background-color: @orange;
|
||||
color: @white;
|
||||
text-shadow: none;
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: @white;
|
||||
}
|
||||
|
||||
&-error {
|
||||
background-color: @red;
|
||||
}
|
||||
|
||||
&-success {
|
||||
background-color: @green;
|
||||
}
|
||||
|
||||
&-info {
|
||||
background-color: @blue;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
padding: 6px 10px;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.badge {
|
||||
padding: 6px 10px;
|
||||
.border-radius(@borderRadiusLarge);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
// MISC
|
||||
// --------------------------------------------------
|
||||
|
||||
.well {
|
||||
border: none;
|
||||
.box-shadow(none);
|
||||
|
||||
}
|
||||
|
||||
.progress {
|
||||
|
||||
background: @grayLighter;
|
||||
border-radius: 32px;
|
||||
height: 12px;
|
||||
.box-shadow(none);
|
||||
|
||||
.bar {
|
||||
background-color: @blueDark;
|
||||
background-image: none;
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
.bar + .bar {
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
&-striped .bar {
|
||||
#gradient > .striped(@blueDark);
|
||||
}
|
||||
|
||||
&-success .bar,
|
||||
&-success.progress-striped .bar,
|
||||
.bar-success {
|
||||
background-color: @green;
|
||||
}
|
||||
|
||||
&-warning .bar,
|
||||
&-warning.progress-striped .bar,
|
||||
.bar-warning {
|
||||
background-color: @yellow;
|
||||
}
|
||||
|
||||
&-danger .bar,
|
||||
&-danger.progress-striped .bar,
|
||||
.bar-danger {
|
||||
background-color: @red;
|
||||
}
|
||||
|
||||
&-info .bar,
|
||||
&-info.progress-striped .bar,
|
||||
.bar-info {
|
||||
background-color: @blue;
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
|
||||
&.in {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.popover {
|
||||
color: @white;
|
||||
|
||||
&-title {
|
||||
border-bottom: 2px solid @dropdownDividerBottom;
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
|
||||
&-header {
|
||||
background-color: @navbarBackground;
|
||||
border-bottom: none;
|
||||
color: @white;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
background-color: @grayLighter;
|
||||
border-top: none;
|
||||
.box-shadow(none);
|
||||
}
|
||||
}
|
||||
|
||||
.close {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
// MEDIA QUERIES
|
||||
// --------------------------------------------------
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
div.subnav {
|
||||
|
||||
.nav > li:first-child > a,
|
||||
.nav > li + li > a {
|
||||
border-color: transparent;
|
||||
|
||||
&:hover {
|
||||
background-color: darken(@grayLighter, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.nav > li:last-child > a {
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-append,
|
||||
.input-prepend {
|
||||
|
||||
.add-on,.btn {
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 979px) {
|
||||
|
||||
.navbar {
|
||||
|
||||
.nav-collapse .nav > li > a {
|
||||
color: @white;
|
||||
|
||||
&:hover {
|
||||
background-color: @green;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
300
src/bootstrap/css/variables.less
Normal file
|
@ -0,0 +1,300 @@
|
|||
// Flatness by Jenil (www.jgog.in)
|
||||
// Bootswatch 2.3.2
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
// Global values
|
||||
// --------------------------------------------------
|
||||
|
||||
// Grays
|
||||
// -------------------------
|
||||
@black: #000;
|
||||
@grayDarker: #222;
|
||||
@grayDark: #7b8a8b;
|
||||
@gray: #95A5A6;
|
||||
@grayLight: #b4bcc2;
|
||||
@grayLighter: #ECF0F1;
|
||||
@white: #fff;
|
||||
|
||||
|
||||
// Accent colors
|
||||
// -------------------------
|
||||
@blue: #3498DB;
|
||||
@blueDark: #2C3E50;
|
||||
@green: #18BC9C;
|
||||
@red: #E74C3C;
|
||||
@yellow: #e6bb0d;
|
||||
@orange: #F39C12;
|
||||
@pink: #ff6699;
|
||||
@purple: #8E44AD;
|
||||
|
||||
|
||||
// Scaffolding
|
||||
// -------------------------
|
||||
@bodyBackground: @white;
|
||||
@textColor: @blueDark;
|
||||
|
||||
|
||||
// Links
|
||||
// -------------------------
|
||||
@linkColor: #1ABC9C;
|
||||
@linkColorHover: lighten(@linkColor, 5%);
|
||||
|
||||
|
||||
// Typography
|
||||
// -------------------------
|
||||
@sansFontFamily: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
@serifFontFamily: Georgia, "Times New Roman", Times, serif;
|
||||
@monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
|
||||
@baseFontSize: 15px;
|
||||
@baseFontFamily: @sansFontFamily;
|
||||
@baseLineHeight: 20px;
|
||||
@altFontFamily: @serifFontFamily;
|
||||
|
||||
@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily
|
||||
@headingsFontWeight: bold; // instead of browser default, bold
|
||||
@headingsColor: inherit; // empty to use BS default, @textColor
|
||||
|
||||
|
||||
// Component sizing
|
||||
// -------------------------
|
||||
// Based on 14px font-size and 20px line-height
|
||||
|
||||
@fontSizeLarge: @baseFontSize * 1.25; // ~18px
|
||||
@fontSizeSmall: @baseFontSize * 0.85; // ~12px
|
||||
@fontSizeMini: @baseFontSize * 0.75; // ~11px
|
||||
|
||||
@paddingLarge: 18px 36px; // 44px
|
||||
@paddingSmall: 2px 12px; // 26px
|
||||
@paddingMini: 1px 8px; // 24px
|
||||
|
||||
@baseBorderRadius: 6px;
|
||||
@borderRadiusLarge: 10px;
|
||||
@borderRadiusSmall: 3px;
|
||||
|
||||
|
||||
// Tables
|
||||
// -------------------------
|
||||
@tableBackground: transparent; // overall background-color
|
||||
@tableBackgroundAccent: #f9f9f9; // for striping
|
||||
@tableBackgroundHover: #f5f5f5; // for hover
|
||||
@tableBorder: #ddd; // table and cell border
|
||||
|
||||
// Buttons
|
||||
// -------------------------
|
||||
@btnBackground: @grayLight;
|
||||
@btnBackgroundHighlight: lighten(@btnBackground, 10%);
|
||||
@btnBorder: #ddd;
|
||||
|
||||
@btnPrimaryBackground: @textColor;
|
||||
@btnPrimaryBackgroundHighlight: lighten(@btnPrimaryBackground, 10%);
|
||||
|
||||
@btnInfoBackground: @blue;
|
||||
@btnInfoBackgroundHighlight: lighten(@btnInfoBackground, 10%);
|
||||
|
||||
@btnSuccessBackground: @green;
|
||||
@btnSuccessBackgroundHighlight: lighten(@btnSuccessBackground, 10%);
|
||||
|
||||
@btnWarningBackground: @orange;
|
||||
@btnWarningBackgroundHighlight: lighten(@btnWarningBackground, 10%);
|
||||
|
||||
@btnDangerBackground: @red;
|
||||
@btnDangerBackgroundHighlight: lighten(@btnDangerBackground, 10%);
|
||||
|
||||
@btnInverseBackground: @grayDarker;
|
||||
@btnInverseBackgroundHighlight: lighten(@btnInverseBackground, 10%);
|
||||
|
||||
|
||||
// Forms
|
||||
// -------------------------
|
||||
@inputBackground: @white;
|
||||
@inputBorder: #dce4ec;
|
||||
@inputBorderRadius: @baseBorderRadius;
|
||||
@inputDisabledBackground: #eaeded;
|
||||
@formActionsBackground: #f5f5f5;
|
||||
@inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border
|
||||
|
||||
|
||||
// Dropdowns
|
||||
// -------------------------
|
||||
@dropdownBackground: @blueDark;
|
||||
@dropdownBorder: rgba(0,0,0,0);
|
||||
@dropdownDividerTop: rgba(0,0,0,0.2);
|
||||
@dropdownDividerBottom: rgba(0,0,0,0.2);
|
||||
|
||||
@dropdownLinkColor: @white;
|
||||
@dropdownLinkColorHover: @white;
|
||||
@dropdownLinkColorActive: @dropdownLinkColor;
|
||||
|
||||
@dropdownLinkBackgroundActive: @green;
|
||||
@dropdownLinkBackgroundHover: @green;
|
||||
|
||||
|
||||
|
||||
// COMPONENT VARIABLES
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
// Z-index master list
|
||||
// -------------------------
|
||||
// Used for a bird's eye view of components dependent on the z-axis
|
||||
// Try to avoid customizing these :)
|
||||
@zindexDropdown: 1000;
|
||||
@zindexPopover: 1010;
|
||||
@zindexTooltip: 1030;
|
||||
@zindexFixedNavbar: 1030;
|
||||
@zindexModalBackdrop: 1040;
|
||||
@zindexModal: 1050;
|
||||
|
||||
|
||||
// Sprite icons path
|
||||
// -------------------------
|
||||
@iconSpritePath: "../img/glyphicons-halflings.png";
|
||||
@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png";
|
||||
|
||||
|
||||
// Input placeholder text color
|
||||
// -------------------------
|
||||
@placeholderText: @grayLight;
|
||||
|
||||
|
||||
// Hr border color
|
||||
// -------------------------
|
||||
@hrBorder: @grayLighter;
|
||||
|
||||
|
||||
// Horizontal forms & lists
|
||||
// -------------------------
|
||||
@horizontalComponentOffset: 180px;
|
||||
|
||||
|
||||
// Wells
|
||||
// -------------------------
|
||||
@wellBackground: @grayLighter;
|
||||
|
||||
|
||||
// Navbar
|
||||
// -------------------------
|
||||
@navbarCollapseWidth: 979px;
|
||||
@navbarCollapseDesktopWidth: @navbarCollapseWidth + 1;
|
||||
|
||||
@navbarHeight: 50px;
|
||||
@navbarBackgroundHighlight: @textColor;
|
||||
@navbarBackground: @textColor;
|
||||
@navbarBorder: darken(@navbarBackground, 5%);
|
||||
|
||||
@navbarText: @white;
|
||||
@navbarLinkColor: @white;
|
||||
@navbarLinkColorHover: @linkColor;
|
||||
@navbarLinkColorActive: @linkColor;
|
||||
@navbarLinkBackgroundHover: transparent;
|
||||
@navbarLinkBackgroundActive: darken(@navbarBackground, 5%);
|
||||
|
||||
@navbarBrandColor: @navbarLinkColor;
|
||||
|
||||
// Inverted navbar
|
||||
@navbarInverseBackground: @green;
|
||||
@navbarInverseBackgroundHighlight: @green;
|
||||
@navbarInverseBorder: darken(@green, 5%);
|
||||
|
||||
@navbarInverseText: @white;
|
||||
@navbarInverseLinkColor: @white;
|
||||
@navbarInverseLinkColorHover: @blueDark;
|
||||
@navbarInverseLinkColorActive: @blueDark;
|
||||
@navbarInverseLinkBackgroundHover: transparent;
|
||||
@navbarInverseLinkBackgroundActive: darken(@navbarInverseBackground, 5%);
|
||||
|
||||
@navbarInverseSearchBackground: @white;
|
||||
@navbarInverseSearchBackgroundFocus: @white;
|
||||
@navbarInverseSearchBorder: @grayLight;
|
||||
@navbarInverseSearchPlaceholderColor: @gray;
|
||||
|
||||
@navbarInverseBrandColor: @navbarInverseLinkColor;
|
||||
|
||||
|
||||
// Pagination
|
||||
// -------------------------
|
||||
@paginationBackground: #fff;
|
||||
@paginationBorder: #ddd;
|
||||
@paginationActiveBackground: @grayLighter;
|
||||
|
||||
|
||||
// Hero unit
|
||||
// -------------------------
|
||||
@heroUnitBackground: @grayLighter;
|
||||
@heroUnitHeadingColor: inherit;
|
||||
@heroUnitLeadColor: inherit;
|
||||
|
||||
|
||||
// Form states and alerts
|
||||
// -------------------------
|
||||
@warningText: @yellow;
|
||||
@warningBackground: @yellow;
|
||||
@warningBorder: transparent;
|
||||
|
||||
@errorText: @red;
|
||||
@errorBackground: @red;
|
||||
@errorBorder: transparent;
|
||||
|
||||
@successText: @green;
|
||||
@successBackground: @green;
|
||||
@successBorder: transparent;
|
||||
|
||||
@infoText: @blue;
|
||||
@infoBackground: @blue;
|
||||
@infoBorder: transparent;
|
||||
|
||||
|
||||
// Tooltips and popovers
|
||||
// -------------------------
|
||||
@tooltipColor: #fff;
|
||||
@tooltipBackground: @blueDark;
|
||||
@tooltipArrowWidth: 5px;
|
||||
@tooltipArrowColor: @tooltipBackground;
|
||||
|
||||
@popoverBackground: @blueDark;
|
||||
@popoverArrowWidth: 10px;
|
||||
@popoverArrowColor: @blueDark;
|
||||
@popoverTitleBackground: @blueDark;
|
||||
|
||||
// Special enhancement for popovers
|
||||
@popoverArrowOuterWidth: @popoverArrowWidth + 1;
|
||||
@popoverArrowOuterColor: rgba(0,0,0,.25);
|
||||
|
||||
|
||||
|
||||
// GRID
|
||||
// --------------------------------------------------
|
||||
|
||||
|
||||
// Default 940px grid
|
||||
// -------------------------
|
||||
@gridColumns: 12;
|
||||
@gridColumnWidth: 60px;
|
||||
@gridGutterWidth: 20px;
|
||||
@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1));
|
||||
|
||||
// 1200px min
|
||||
@gridColumnWidth1200: 70px;
|
||||
@gridGutterWidth1200: 30px;
|
||||
@gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1));
|
||||
|
||||
// 768px-979px
|
||||
@gridColumnWidth768: 42px;
|
||||
@gridGutterWidth768: 20px;
|
||||
@gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1));
|
||||
|
||||
|
||||
// Fluid grid
|
||||
// -------------------------
|
||||
@fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth);
|
||||
@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth);
|
||||
|
||||
// 1200px min
|
||||
@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200);
|
||||
@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200);
|
||||
|
||||
// 768px-979px
|
||||
@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768);
|
||||
@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768);
|
BIN
src/bootstrap/img/glyphicons-halflings-white.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
src/bootstrap/img/glyphicons-halflings.png
Normal file
After Width: | Height: | Size: 12 KiB |
2025
src/bootstrap/js/bootstrap.js
vendored
Normal file
6
src/bootstrap/js/bootstrap.min.js
vendored
Normal file
|
@ -20,7 +20,7 @@ $opt = $smarty->opt();
|
|||
|
||||
session_start();
|
||||
if (!isset($_SESSION["userid"])) {
|
||||
header("Location: " . getFullPath("login.php") . "?from=categories.php");
|
||||
header("Location: " . getFullPath("login.php"));
|
||||
exit;
|
||||
}
|
||||
else if ($_SESSION["admin"] != 1) {
|
||||
|
@ -31,50 +31,38 @@ else {
|
|||
$userid = $_SESSION["userid"];
|
||||
}
|
||||
if (!empty($_GET["message"])) {
|
||||
$message = filter_var(trim($_GET["message"], FILTER_SANITIZE_STRING));;
|
||||
$message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
|
||||
$message = $_GET["message"];
|
||||
}
|
||||
|
||||
$haserror = false;
|
||||
$error_message = "";
|
||||
$action = isset($_GET["action"]) ? $_GET["action"] : "";
|
||||
|
||||
if ($action == "insert" || $action == "update") {
|
||||
/* validate the data. */
|
||||
$category = filter_var(trim($_GET["category"]), FILTER_SANITIZE_STRING);
|
||||
$category = htmlspecialchars($category, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$category = trim($_GET["category"]);
|
||||
|
||||
$haserror = false;
|
||||
if ($category == "") {
|
||||
$haserror = true;
|
||||
$error_message = trim("$error_message A category is required.");
|
||||
$category_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET["categoryid"])) {
|
||||
$categoryid = filter_var(trim($_GET["categoryid"]), FILTER_SANITIZE_NUMBER_INT);
|
||||
|
||||
if (filter_var($categoryid, FILTER_SANITIZE_NUMBER_INT) === false || $categoryid == "" || !is_numeric($categoryid) || $categoryid < 0) {
|
||||
die("Invalid categoryid ({$_GET["categoryid"]})");
|
||||
$category_error = "A category is required.";
|
||||
}
|
||||
}
|
||||
|
||||
if ($action == "delete") {
|
||||
/* first, NULL all category FKs for items that use this category. */
|
||||
$stmt = $smarty->dbh()->prepare("UPDATE {$opt["table_prefix"]}items SET category = NULL WHERE category = ?");
|
||||
$stmt->bindValue(1, (int) $categoryid, PDO::PARAM_INT);
|
||||
$stmt->bindValue(1, (int) $_GET["categoryid"], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}categories WHERE categoryid = ?");
|
||||
$stmt->bindValue(1, (int) $categoryid, PDO::PARAM_INT);
|
||||
$stmt->bindValue(1, (int) $_GET["categoryid"], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
header("Location: " . getFullPath("categories.php?message=Category+deleted."));
|
||||
exit;
|
||||
}
|
||||
else if ($action == "edit") {
|
||||
$stmt = $smarty->dbh()->prepare("SELECT category FROM {$opt["table_prefix"]}categories WHERE categoryid = ?");
|
||||
$stmt->bindValue(1, (int) $categoryid, PDO::PARAM_INT);
|
||||
$stmt->bindValue(1, (int) $_GET["categoryid"], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
if ($row = $stmt->fetch()) {
|
||||
$category = $row["category"];
|
||||
|
@ -88,7 +76,7 @@ else if ($action == "insert") {
|
|||
$stmt = $smarty->dbh()->prepare("INSERT INTO {$opt["table_prefix"]}categories(categoryid,category) VALUES(NULL, ?)");
|
||||
$stmt->bindParam(1, $category, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
header("Location: " . getFullPath("categories.php?message=Category+added."));
|
||||
exit;
|
||||
}
|
||||
|
@ -99,11 +87,11 @@ else if ($action == "update") {
|
|||
"SET category = ? " .
|
||||
"WHERE categoryid = ?");
|
||||
$stmt->bindParam(1, $category, PDO::PARAM_STR);
|
||||
$stmt->bindValue(2, (int) $categoryid, PDO::PARAM_INT);
|
||||
$stmt->bindValue(2, (int) $_GET["categoryid"], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
header("Location: " . getFullPath("categories.php?message=Category+updated."));
|
||||
exit;
|
||||
exit;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -125,8 +113,8 @@ if (isset($action)) {
|
|||
$smarty->assign('action', $action);
|
||||
}
|
||||
$smarty->assign('categories', $categories);
|
||||
if (isset($categoryid)) {
|
||||
$smarty->assign('categoryid', (int) $categoryid);
|
||||
if (isset($_GET["categoryid"])) {
|
||||
$smarty->assign('categoryid', (int) $_GET["categoryid"]);
|
||||
}
|
||||
if (isset($message)) {
|
||||
$smarty->assign('message', $message);
|
||||
|
@ -136,8 +124,5 @@ if (isset($category_error)) {
|
|||
$smarty->assign('category_error', $category_error);
|
||||
}
|
||||
$smarty->assign('haserror', isset($haserror) ? $haserror : false);
|
||||
if ($error_message != "") {
|
||||
$smarty->assign('error_message', $error_message);
|
||||
}
|
||||
$smarty->display('categories.tpl');
|
||||
?>
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
.nav-collapse .nav > li > a:hover,
|
||||
.nav-collapse .dropdown-menu a:hover {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.navbar-inverse .nav-collapse .nav > li > a,
|
||||
.navbar-inverse .nav-collapse .dropdown-menu a {
|
||||
color: #999999;
|
||||
}
|
1
src/css/phpgiftrec.min.css
vendored
|
@ -1,20 +0,0 @@
|
|||
/* Ensure the main content takes up available space */
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
.icon {
|
||||
fill: currentcolor;
|
||||
}
|
||||
|
||||
.boldicon {
|
||||
fill: currentcolor;
|
||||
stroke: currentcolor;
|
||||
stroke-width: 1;
|
||||
}
|
7
src/datepicker/css/datepicker.css
Normal file
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
Datepicker for Bootstrap
|
||||
Copyright 2012 Stefan Petre
|
||||
Licensed under the Apache License v2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
.datepicker { top: 0; left: 0; padding: 4px; margin-top: 1px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; /*.dow { border-top: 1px solid #ddd !important; }*/ } .datepicker:before { content: ''; display: inline-block; border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 7px solid #ccc; border-bottom-color: rgba(0, 0, 0, 0.2); position: absolute; top: -7px; left: 6px; } .datepicker:after { content: ''; display: inline-block; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 6px solid #ffffff; position: absolute; top: -6px; left: 7px; } .datepicker > div { display: none; } .datepicker table { width: 100%; margin: 0; } .datepicker td, .datepicker th { text-align: center; width: 20px; height: 20px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td.day:hover { background: #eeeeee; cursor: pointer; } .datepicker td.old, .datepicker td.new { color: #999999; } .datepicker td.active, .datepicker td.active:hover { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td.active:hover, .datepicker td.active:hover:hover, .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active, .datepicker td.active.disabled, .datepicker td.active:hover.disabled, .datepicker td.active[disabled], .datepicker td.active:hover[disabled] { background-color: #0044cc; } .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active { background-color: #003399 \9; } .datepicker td span { display: block; width: 47px; height: 54px; line-height: 54px; float: left; margin: 2px; cursor: pointer; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td span:hover { background: #eeeeee; } .datepicker td span.active { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td span.active:hover, .datepicker td span.active:active, .datepicker td span.active.active, .datepicker td span.active.disabled, .datepicker td span.active[disabled] { background-color: #0044cc; } .datepicker td span.active:active, .datepicker td span.active.active { background-color: #003399 \9; } .datepicker td span.old { color: #999999; } .datepicker th.switch { width: 145px; } .datepicker th.next, .datepicker th.prev { font-size: 19.5px; } .datepicker thead tr:first-child th { cursor: pointer; } .datepicker thead tr:first-child th:hover { background: #eeeeee; } .input-append.date .add-on i, .input-prepend.date .add-on i { display: block; cursor: pointer; width: 16px; height: 16px; }
|
454
src/datepicker/js/bootstrap-datepicker.js
vendored
Normal file
|
@ -0,0 +1,454 @@
|
|||
/* =========================================================
|
||||
* bootstrap-datepicker.js
|
||||
* http://www.eyecon.ro/bootstrap-datepicker
|
||||
* =========================================================
|
||||
* Copyright 2012 Stefan Petre
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================= */
|
||||
|
||||
!function( $ ) {
|
||||
|
||||
// Picker object
|
||||
|
||||
var Datepicker = function(element, options){
|
||||
this.element = $(element);
|
||||
this.format = DPGlobal.parseFormat(options.format||this.element.data('date-format')||'mm/dd/yyyy');
|
||||
this.picker = $(DPGlobal.template)
|
||||
.appendTo('body')
|
||||
.on({
|
||||
click: $.proxy(this.click, this),
|
||||
mousedown: $.proxy(this.mousedown, this)
|
||||
});
|
||||
this.isInput = this.element.is('input');
|
||||
this.component = this.element.is('.date') ? this.element.find('.add-on') : false;
|
||||
|
||||
if (this.isInput) {
|
||||
this.element.on({
|
||||
focus: $.proxy(this.show, this),
|
||||
blur: $.proxy(this.hide, this),
|
||||
keyup: $.proxy(this.update, this)
|
||||
});
|
||||
} else {
|
||||
if (this.component){
|
||||
this.component.on('click', $.proxy(this.show, this));
|
||||
} else {
|
||||
this.element.on('click', $.proxy(this.show, this));
|
||||
}
|
||||
}
|
||||
this.minViewMode = options.minViewMode||this.element.data('date-minviewmode')||0;
|
||||
if (typeof this.minViewMode === 'string') {
|
||||
switch (this.minViewMode) {
|
||||
case 'months':
|
||||
this.minViewMode = 1;
|
||||
break;
|
||||
case 'years':
|
||||
this.minViewMode = 2;
|
||||
break;
|
||||
default:
|
||||
this.minViewMode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.viewMode = options.viewMode||this.element.data('date-viewmode')||0;
|
||||
if (typeof this.viewMode === 'string') {
|
||||
switch (this.viewMode) {
|
||||
case 'months':
|
||||
this.viewMode = 1;
|
||||
break;
|
||||
case 'years':
|
||||
this.viewMode = 2;
|
||||
break;
|
||||
default:
|
||||
this.viewMode = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.startViewMode = this.viewMode;
|
||||
this.weekStart = options.weekStart||this.element.data('date-weekstart')||0;
|
||||
this.weekEnd = this.weekStart === 0 ? 6 : this.weekStart - 1;
|
||||
this.fillDow();
|
||||
this.fillMonths();
|
||||
this.update();
|
||||
this.showMode();
|
||||
};
|
||||
|
||||
Datepicker.prototype = {
|
||||
constructor: Datepicker,
|
||||
|
||||
show: function(e) {
|
||||
this.picker.show();
|
||||
this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();
|
||||
this.place();
|
||||
$(window).on('resize', $.proxy(this.place, this));
|
||||
if (e ) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
if (!this.isInput) {
|
||||
$(document).on('mousedown', $.proxy(this.hide, this));
|
||||
}
|
||||
this.element.trigger({
|
||||
type: 'show',
|
||||
date: this.date
|
||||
});
|
||||
},
|
||||
|
||||
hide: function(){
|
||||
this.picker.hide();
|
||||
$(window).off('resize', this.place);
|
||||
this.viewMode = this.startViewMode;
|
||||
this.showMode();
|
||||
if (!this.isInput) {
|
||||
$(document).off('mousedown', this.hide);
|
||||
}
|
||||
this.set();
|
||||
this.element.trigger({
|
||||
type: 'hide',
|
||||
date: this.date
|
||||
});
|
||||
},
|
||||
|
||||
set: function() {
|
||||
var formated = DPGlobal.formatDate(this.date, this.format);
|
||||
if (!this.isInput) {
|
||||
if (this.component){
|
||||
this.element.find('input').prop('value', formated);
|
||||
}
|
||||
this.element.data('date', formated);
|
||||
} else {
|
||||
this.element.prop('value', formated);
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function(newDate) {
|
||||
if (typeof newDate === 'string') {
|
||||
this.date = DPGlobal.parseDate(newDate, this.format);
|
||||
} else {
|
||||
this.date = new Date(newDate);
|
||||
}
|
||||
this.set();
|
||||
this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
|
||||
this.fill();
|
||||
},
|
||||
|
||||
place: function(){
|
||||
var offset = this.component ? this.component.offset() : this.element.offset();
|
||||
this.picker.css({
|
||||
top: offset.top + this.height,
|
||||
left: offset.left
|
||||
});
|
||||
},
|
||||
|
||||
update: function(newDate){
|
||||
this.date = DPGlobal.parseDate(
|
||||
typeof newDate === 'string' ? newDate : (this.isInput ? this.element.prop('value') : this.element.data('date')),
|
||||
this.format
|
||||
);
|
||||
this.viewDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0, 0);
|
||||
this.fill();
|
||||
},
|
||||
|
||||
fillDow: function(){
|
||||
var dowCnt = this.weekStart;
|
||||
var html = '<tr>';
|
||||
while (dowCnt < this.weekStart + 7) {
|
||||
html += '<th class="dow">'+DPGlobal.dates.daysMin[(dowCnt++)%7]+'</th>';
|
||||
}
|
||||
html += '</tr>';
|
||||
this.picker.find('.datepicker-days thead').append(html);
|
||||
},
|
||||
|
||||
fillMonths: function(){
|
||||
var html = '';
|
||||
var i = 0
|
||||
while (i < 12) {
|
||||
html += '<span class="month">'+DPGlobal.dates.monthsShort[i++]+'</span>';
|
||||
}
|
||||
this.picker.find('.datepicker-months td').append(html);
|
||||
},
|
||||
|
||||
fill: function() {
|
||||
var d = new Date(this.viewDate),
|
||||
year = d.getFullYear(),
|
||||
month = d.getMonth(),
|
||||
currentDate = this.date.valueOf();
|
||||
this.picker.find('.datepicker-days th:eq(1)')
|
||||
.text(DPGlobal.dates.months[month]+' '+year);
|
||||
var prevMonth = new Date(year, month-1, 28,0,0,0,0),
|
||||
day = DPGlobal.getDaysInMonth(prevMonth.getFullYear(), prevMonth.getMonth());
|
||||
prevMonth.setDate(day);
|
||||
prevMonth.setDate(day - (prevMonth.getDay() - this.weekStart + 7)%7);
|
||||
var nextMonth = new Date(prevMonth);
|
||||
nextMonth.setDate(nextMonth.getDate() + 42);
|
||||
nextMonth = nextMonth.valueOf();
|
||||
html = [];
|
||||
var clsName;
|
||||
while(prevMonth.valueOf() < nextMonth) {
|
||||
if (prevMonth.getDay() === this.weekStart) {
|
||||
html.push('<tr>');
|
||||
}
|
||||
clsName = '';
|
||||
if (prevMonth.getMonth() < month) {
|
||||
clsName += ' old';
|
||||
} else if (prevMonth.getMonth() > month) {
|
||||
clsName += ' new';
|
||||
}
|
||||
if (prevMonth.valueOf() === currentDate) {
|
||||
clsName += ' active';
|
||||
}
|
||||
html.push('<td class="day'+clsName+'">'+prevMonth.getDate() + '</td>');
|
||||
if (prevMonth.getDay() === this.weekEnd) {
|
||||
html.push('</tr>');
|
||||
}
|
||||
prevMonth.setDate(prevMonth.getDate()+1);
|
||||
}
|
||||
this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
|
||||
var currentYear = this.date.getFullYear();
|
||||
|
||||
var months = this.picker.find('.datepicker-months')
|
||||
.find('th:eq(1)')
|
||||
.text(year)
|
||||
.end()
|
||||
.find('span').removeClass('active');
|
||||
if (currentYear === year) {
|
||||
months.eq(this.date.getMonth()).addClass('active');
|
||||
}
|
||||
|
||||
html = '';
|
||||
year = parseInt(year/10, 10) * 10;
|
||||
var yearCont = this.picker.find('.datepicker-years')
|
||||
.find('th:eq(1)')
|
||||
.text(year + '-' + (year + 9))
|
||||
.end()
|
||||
.find('td');
|
||||
year -= 1;
|
||||
for (var i = -1; i < 11; i++) {
|
||||
html += '<span class="year'+(i === -1 || i === 10 ? ' old' : '')+(currentYear === year ? ' active' : '')+'">'+year+'</span>';
|
||||
year += 1;
|
||||
}
|
||||
yearCont.html(html);
|
||||
},
|
||||
|
||||
click: function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
var target = $(e.target).closest('span, td, th');
|
||||
if (target.length === 1) {
|
||||
switch(target[0].nodeName.toLowerCase()) {
|
||||
case 'th':
|
||||
switch(target[0].className) {
|
||||
case 'switch':
|
||||
this.showMode(1);
|
||||
break;
|
||||
case 'prev':
|
||||
case 'next':
|
||||
this.viewDate['set'+DPGlobal.modes[this.viewMode].navFnc].call(
|
||||
this.viewDate,
|
||||
this.viewDate['get'+DPGlobal.modes[this.viewMode].navFnc].call(this.viewDate) +
|
||||
DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1)
|
||||
);
|
||||
this.fill();
|
||||
this.set();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'span':
|
||||
if (target.is('.month')) {
|
||||
var month = target.parent().find('span').index(target);
|
||||
this.viewDate.setMonth(month);
|
||||
} else {
|
||||
var year = parseInt(target.text(), 10)||0;
|
||||
this.viewDate.setFullYear(year);
|
||||
}
|
||||
if (this.viewMode !== 0) {
|
||||
this.date = new Date(this.viewDate);
|
||||
this.element.trigger({
|
||||
type: 'changeDate',
|
||||
date: this.date,
|
||||
viewMode: DPGlobal.modes[this.viewMode].clsName
|
||||
});
|
||||
}
|
||||
this.showMode(-1);
|
||||
this.fill();
|
||||
this.set();
|
||||
break;
|
||||
case 'td':
|
||||
if (target.is('.day')){
|
||||
var day = parseInt(target.text(), 10)||1;
|
||||
var month = this.viewDate.getMonth();
|
||||
if (target.is('.old')) {
|
||||
month -= 1;
|
||||
} else if (target.is('.new')) {
|
||||
month += 1;
|
||||
}
|
||||
var year = this.viewDate.getFullYear();
|
||||
this.date = new Date(year, month, day,0,0,0,0);
|
||||
this.viewDate = new Date(year, month, Math.min(28, day),0,0,0,0);
|
||||
this.fill();
|
||||
this.set();
|
||||
this.element.trigger({
|
||||
type: 'changeDate',
|
||||
date: this.date,
|
||||
viewMode: DPGlobal.modes[this.viewMode].clsName
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mousedown: function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
},
|
||||
|
||||
showMode: function(dir) {
|
||||
if (dir) {
|
||||
this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
|
||||
}
|
||||
this.picker.find('>div').hide().filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName).show();
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.datepicker = function ( option, val ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this),
|
||||
data = $this.data('datepicker'),
|
||||
options = typeof option === 'object' && option;
|
||||
if (!data) {
|
||||
$this.data('datepicker', (data = new Datepicker(this, $.extend({}, $.fn.datepicker.defaults,options))));
|
||||
}
|
||||
if (typeof option === 'string') data[option](val);
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.datepicker.defaults = {
|
||||
};
|
||||
$.fn.datepicker.Constructor = Datepicker;
|
||||
|
||||
var DPGlobal = {
|
||||
modes: [
|
||||
{
|
||||
clsName: 'days',
|
||||
navFnc: 'Month',
|
||||
navStep: 1
|
||||
},
|
||||
{
|
||||
clsName: 'months',
|
||||
navFnc: 'FullYear',
|
||||
navStep: 1
|
||||
},
|
||||
{
|
||||
clsName: 'years',
|
||||
navFnc: 'FullYear',
|
||||
navStep: 10
|
||||
}],
|
||||
dates:{
|
||||
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
|
||||
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||||
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
|
||||
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
||||
},
|
||||
isLeapYear: function (year) {
|
||||
return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))
|
||||
},
|
||||
getDaysInMonth: function (year, month) {
|
||||
return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
|
||||
},
|
||||
parseFormat: function(format){
|
||||
var separator = format.match(/[.\/\-\s].*?/),
|
||||
parts = format.split(/\W+/);
|
||||
if (!separator || !parts || parts.length === 0){
|
||||
throw new Error("Invalid date format.");
|
||||
}
|
||||
return {separator: separator, parts: parts};
|
||||
},
|
||||
parseDate: function(date, format) {
|
||||
var parts = date.split(format.separator),
|
||||
date = new Date(),
|
||||
val;
|
||||
date.setHours(0);
|
||||
date.setMinutes(0);
|
||||
date.setSeconds(0);
|
||||
date.setMilliseconds(0);
|
||||
if (parts.length === format.parts.length) {
|
||||
for (var i=0, cnt = format.parts.length; i < cnt; i++) {
|
||||
val = parseInt(parts[i], 10)||1;
|
||||
switch(format.parts[i]) {
|
||||
case 'dd':
|
||||
case 'd':
|
||||
date.setDate(val);
|
||||
break;
|
||||
case 'mm':
|
||||
case 'm':
|
||||
date.setMonth(val - 1);
|
||||
break;
|
||||
case 'yy':
|
||||
date.setFullYear(2000 + val);
|
||||
break;
|
||||
case 'yyyy':
|
||||
date.setFullYear(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return date;
|
||||
},
|
||||
formatDate: function(date, format){
|
||||
var val = {
|
||||
d: date.getDate(),
|
||||
m: date.getMonth() + 1,
|
||||
yy: date.getFullYear().toString().substring(2),
|
||||
yyyy: date.getFullYear()
|
||||
};
|
||||
val.dd = (val.d < 10 ? '0' : '') + val.d;
|
||||
val.mm = (val.m < 10 ? '0' : '') + val.m;
|
||||
var date = [];
|
||||
for (var i=0, cnt = format.parts.length; i < cnt; i++) {
|
||||
date.push(val[format.parts[i]]);
|
||||
}
|
||||
return date.join(format.separator);
|
||||
},
|
||||
headTemplate: '<thead>'+
|
||||
'<tr>'+
|
||||
'<th class="prev">‹</th>'+
|
||||
'<th colspan="5" class="switch"></th>'+
|
||||
'<th class="next">›</th>'+
|
||||
'</tr>'+
|
||||
'</thead>',
|
||||
contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>'
|
||||
};
|
||||
DPGlobal.template = '<div class="datepicker dropdown-menu">'+
|
||||
'<div class="datepicker-days">'+
|
||||
'<table class=" table-condensed">'+
|
||||
DPGlobal.headTemplate+
|
||||
'<tbody></tbody>'+
|
||||
'</table>'+
|
||||
'</div>'+
|
||||
'<div class="datepicker-months">'+
|
||||
'<table class="table-condensed">'+
|
||||
DPGlobal.headTemplate+
|
||||
DPGlobal.contTemplate+
|
||||
'</table>'+
|
||||
'</div>'+
|
||||
'<div class="datepicker-years">'+
|
||||
'<table class="table-condensed">'+
|
||||
DPGlobal.headTemplate+
|
||||
DPGlobal.contTemplate+
|
||||
'</table>'+
|
||||
'</div>'+
|
||||
'</div>';
|
||||
|
||||
}( window.jQuery )
|
119
src/datepicker/less/datepicker.less
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*!
|
||||
* Datepicker for Bootstrap
|
||||
*
|
||||
* Copyright 2012 Stefan Petre
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*/
|
||||
|
||||
.datepicker {
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 4px;
|
||||
margin-top: 1px;
|
||||
.border-radius(4px);
|
||||
&:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-bottom-color: rgba(0,0,0,.2);
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
&:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid @white;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
>div {
|
||||
display: none;
|
||||
}
|
||||
table{
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
td,
|
||||
th{
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
.border-radius(4px);
|
||||
}
|
||||
td {
|
||||
&.day:hover {
|
||||
background: @grayLighter;
|
||||
cursor: pointer;
|
||||
}
|
||||
&.old,
|
||||
&.new {
|
||||
color: @grayLight;
|
||||
}
|
||||
&.active,
|
||||
&.active:hover {
|
||||
.buttonBackground(@primaryButtonBackground, spin(@primaryButtonBackground, 20));
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
span {
|
||||
display: block;
|
||||
width: 47px;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
float: left;
|
||||
margin: 2px;
|
||||
cursor: pointer;
|
||||
.border-radius(4px);
|
||||
&:hover {
|
||||
background: @grayLighter;
|
||||
}
|
||||
&.active {
|
||||
.buttonBackground(@primaryButtonBackground, spin(@primaryButtonBackground, 20));
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
&.old {
|
||||
color: @grayLight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
&.switch {
|
||||
width: 145px;
|
||||
}
|
||||
&.next,
|
||||
&.prev {
|
||||
font-size: @baseFontSize * 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
thead tr:first-child th {
|
||||
cursor: pointer;
|
||||
&:hover{
|
||||
background: @grayLighter;
|
||||
}
|
||||
}
|
||||
/*.dow {
|
||||
border-top: 1px solid #ddd !important;
|
||||
}*/
|
||||
}
|
||||
.input-append,
|
||||
.input-prepend {
|
||||
&.date {
|
||||
.add-on i {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ $opt = $smarty->opt();
|
|||
|
||||
session_start();
|
||||
if (!isset($_SESSION["userid"])) {
|
||||
header("Location: " . getFullPath("login.php") . "?from=event.php");
|
||||
header("Location: " . getFullPath("login.php"));
|
||||
exit;
|
||||
}
|
||||
else {
|
||||
|
@ -28,21 +28,13 @@ else {
|
|||
}
|
||||
|
||||
if (!empty($_GET["message"])) {
|
||||
$message = filter_var(trim($_GET["message"], FILTER_SANITIZE_STRING));;
|
||||
$message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
|
||||
$message = $_GET["message"];
|
||||
}
|
||||
|
||||
if (isset($_GET["eventid"])) {
|
||||
$eventid = filter_var(trim($_GET["eventid"]), FILTER_SANITIZE_NUMBER_INT);
|
||||
|
||||
if (filter_var($eventid, FILTER_SANITIZE_NUMBER_INT) === false || $eventid == "" || !is_numeric($eventid) || $eventid < 0) {
|
||||
die("Invalid eventid ({$_GET["eventid"]})");
|
||||
}
|
||||
$eventid = $_GET["eventid"];
|
||||
}
|
||||
|
||||
$haserror = false;
|
||||
$error_message = "";
|
||||
|
||||
// for security, let's make sure that if an eventid was passed in, it belongs
|
||||
// to $userid (or is a system event and the user is an admin).
|
||||
// all operations on this page should only be performed by the event's owner.
|
||||
|
@ -70,7 +62,7 @@ $action = isset($_GET["action"]) ? $_GET["action"] : "";
|
|||
|
||||
if ($action == "insert" || $action == "update") {
|
||||
/* validate the data. */
|
||||
$description = filter_var(trim($_GET["description"], FILTER_SANITIZE_STRING));;
|
||||
$description = trim($_GET["description"]);
|
||||
try {
|
||||
$eventdate = new DateTime($_GET["eventdate"]);
|
||||
}
|
||||
|
@ -79,16 +71,15 @@ if ($action == "insert" || $action == "update") {
|
|||
}
|
||||
$recurring = (strtoupper($_GET["recurring"]) == "ON" ? 1 : 0);
|
||||
$systemevent = (strtoupper($_GET["systemevent"]) == "ON" ? 1 : 0);
|
||||
|
||||
|
||||
$haserror = false;
|
||||
if ($description == "") {
|
||||
$haserror = true;
|
||||
$error_message = trim("$error_message A description is required.");
|
||||
$description_error = true;
|
||||
$description_error = "A description is required.";
|
||||
}
|
||||
if ($eventdate == FALSE) {
|
||||
$haserror = true;
|
||||
$error_message = trim("$error_message Date is out of range for this server.");
|
||||
$eventdate_error = true;
|
||||
$eventdate_error = "Date is out of range for this server.";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +101,7 @@ else if ($action == "edit") {
|
|||
try {
|
||||
$stmt = $smarty->dbh()->prepare("SELECT description, eventdate, recurring, userid FROM {$opt["table_prefix"]}events WHERE eventid = ?");
|
||||
$stmt->bindParam(1, $eventid, PDO::PARAM_INT);
|
||||
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
// we know this will work, see above.
|
||||
|
@ -140,7 +131,7 @@ else if ($action == "insert") {
|
|||
$stmt->bindParam(4, $recurring, PDO::PARAM_BOOL);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
header("Location: " . getFullPath("event.php?message=Event+added."));
|
||||
exit;
|
||||
}
|
||||
|
@ -156,7 +147,7 @@ else if ($action == "update") {
|
|||
"userid = ?, " .
|
||||
"description = ?, " .
|
||||
"eventdate = ?, " .
|
||||
"recurring = ? " .
|
||||
"recurring = ? " .
|
||||
"WHERE eventid = ?");
|
||||
$stmt->bindValue(1, $systemevent ? NULL : $userid, PDO::PARAM_BOOL);
|
||||
$stmt->bindParam(2, $description, PDO::PARAM_STR);
|
||||
|
@ -207,9 +198,6 @@ try {
|
|||
}
|
||||
$smarty->assign('action', $action);
|
||||
$smarty->assign('haserror', isset($haserror) ? $haserror : false);
|
||||
if ($error_message != "") {
|
||||
$smarty->assign('error_message', $error_message);
|
||||
}
|
||||
$smarty->assign('events', $events);
|
||||
$smarty->assign('eventdate', $eventdate->format($opt["date_format"]));
|
||||
if (isset($eventdate_error)) {
|
||||
|
|
|
@ -19,10 +19,8 @@ $smarty = new MySmarty();
|
|||
$opt = $smarty->opt();
|
||||
|
||||
session_start();
|
||||
$haserror = false;
|
||||
$error_message = "";
|
||||
if (!isset($_SESSION["userid"])) {
|
||||
header("Location: " . getFullPath("login.php") . "?from=families.php");
|
||||
header("Location: " . getFullPath("login.php"));
|
||||
exit;
|
||||
}
|
||||
else if ($_SESSION["admin"] != 1) {
|
||||
|
@ -33,44 +31,22 @@ else {
|
|||
$userid = $_SESSION["userid"];
|
||||
}
|
||||
if (!empty($_GET["message"])) {
|
||||
$message = filter_var(trim($_GET["message"], FILTER_SANITIZE_STRING));;
|
||||
$message = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
|
||||
$message = $_GET["message"];
|
||||
}
|
||||
|
||||
$action = empty($_GET["action"]) ? "" : $_GET["action"];
|
||||
|
||||
if (isset($_GET["familyid"])) {
|
||||
$familyid = filter_var(trim($_GET["familyid"]), FILTER_SANITIZE_NUMBER_INT);
|
||||
|
||||
if (filter_var($familyid, FILTER_SANITIZE_NUMBER_INT) === false || $familyid == "" || !is_numeric($familyid) || $familyid < 0) {
|
||||
die("Invalid familyid ({$_GET["familyid"]})");
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($familyid)) $familyid = 1;
|
||||
|
||||
if (isset($_GET["members"])) {
|
||||
$members = isset($_GET["members"]) ? $_GET["members"] : array();
|
||||
if (!is_array($members)) {
|
||||
die("Invalid data for members ({$_GET["members"]})");
|
||||
}
|
||||
foreach ($members as $index => $member) {
|
||||
$members[$index] = filter_var($member, FILTER_SANITIZE_NUMBER_INT);
|
||||
if (filter_var($members[$index], FILTER_SANITIZE_NUMBER_INT) === false) {
|
||||
die("Invalid data for members ({$_GET["members"]})");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($_GET["familyid"]))
|
||||
$familyid = (int) $_GET["familyid"];
|
||||
|
||||
if ($action == "insert" || $action == "update") {
|
||||
/* validate the data. */
|
||||
$familyname = filter_var(trim($_GET["familyname"]), FILTER_SANITIZE_STRING);
|
||||
$familyname = htmlspecialchars($familyname, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$familyname = trim($_GET["familyname"]);
|
||||
|
||||
$haserror = false;
|
||||
if ($familyname == "") {
|
||||
$haserror = true;
|
||||
$error_message = "A family name is required.";
|
||||
$familyname_error = true;
|
||||
$familyname_error = "A family name is required.";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,7 +60,7 @@ if ($action == "delete") {
|
|||
$stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}families WHERE familyid = ?");
|
||||
$stmt->bindValue(1, $familyid, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
header("Location: " . getFullPath("families.php?message=Family+deleted."));
|
||||
exit;
|
||||
}
|
||||
|
@ -121,7 +97,7 @@ else if ($action == "insert") {
|
|||
catch (PDOException $e) {
|
||||
die("sql exception: " . $e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
header("Location: " . getFullPath("families.php?message=Family+added."));
|
||||
exit;
|
||||
}
|
||||
|
@ -139,12 +115,13 @@ else if ($action == "update") {
|
|||
catch (PDOException $e) {
|
||||
die("sql exception: " . $e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
header("Location: " . getFullPath("families.php?message=Family+updated."));
|
||||
exit;
|
||||
exit;
|
||||
}
|
||||
}
|
||||
else if ($action == "members") {
|
||||
$members = isset($_GET["members"]) ? $_GET["members"] : array();
|
||||
try {
|
||||
/* first, delete all memberships for this family. */
|
||||
$stmt = $smarty->dbh()->prepare("DELETE FROM {$opt["table_prefix"]}memberships WHERE familyid = ?");
|
||||
|
@ -162,7 +139,7 @@ else if ($action == "members") {
|
|||
catch (PDOException $e) {
|
||||
die("sql exception: " . $e->getMessage());
|
||||
}
|
||||
|
||||
|
||||
header("Location: " . getFullPath("families.php?message=Members+changed."));
|
||||
exit;
|
||||
}
|
||||
|
@ -196,14 +173,11 @@ try {
|
|||
|
||||
$smarty->assign('action', $action);
|
||||
$smarty->assign('haserror', $haserror);
|
||||
if ($error_message != "") {
|
||||
$smarty->assign('error_message', $error_message);
|
||||
}
|
||||
if (isset($familyname_error)) {
|
||||
$smarty->assign('familyname_error', $familyname_error);
|
||||
}
|
||||
$smarty->assign('families', $families);
|
||||
$smarty->assign('familyid', $familyid);
|
||||
$smarty->assign('familyid', $familyid);
|
||||
$smarty->assign('familyname', $familyname);
|
||||
if (isset($nonmembers)) {
|
||||
$smarty->assign('nonmembers', $nonmembers);
|
||||
|
|
BIN
src/favicon.ico
Before Width: | Height: | Size: 68 KiB |
|
@ -22,14 +22,14 @@ if (isset($_POST["action"]) && $_POST["action"] == "forgot") {
|
|||
$username = $_POST["username"];
|
||||
|
||||
try {
|
||||
// make sure that username is valid
|
||||
// make sure that username is valid
|
||||
$stmt = $smarty->dbh()->prepare("SELECT email FROM {$opt["table_prefix"]}users WHERE username = ?");
|
||||
$stmt->bindParam(1, $username, PDO::PARAM_STR);
|
||||
|
||||
|
||||
$stmt->execute();
|
||||
if ($row = $stmt->fetch()) {
|
||||
$email = $row["email"];
|
||||
|
||||
|
||||
if ($email == "")
|
||||
$error = "The username '" . $username . "' does not have an e-mail address, so the password could not be sent.";
|
||||
else {
|
||||
|
@ -42,7 +42,7 @@ if (isset($_POST["action"]) && $_POST["action"] == "forgot") {
|
|||
mail(
|
||||
$email,
|
||||
"Gift Registry password reset",
|
||||
"Your Gift Registry account information:\r\n" .
|
||||
"Your Gift Registry account information:\r\n" .
|
||||
"Your username is '" . $username . "' and your new password is '$pwd'.",
|
||||
"From: {$opt["email_from"]}\r\nReply-To: {$opt["email_reply_to"]}\r\nX-Mailer: {$opt["email_xmailer"]}\r\n"
|
||||
) or die("Mail not accepted for $email");
|
||||
|
@ -64,8 +64,6 @@ if (isset($_POST["action"]) && $_POST["action"] == "forgot") {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!isset($username)) $username = "";
|
||||
$smarty->assign('username', $username);
|
||||
$smarty->display('forgot.tpl');
|
||||
}
|
||||
?>
|
||||
|
|
76
src/help.php
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
require_once(dirname(__FILE__) . "/includes/funcLib.php");
|
||||
require_once(dirname(__FILE__) . "/includes/MySmarty.class.php");
|
||||
$smarty = new MySmarty();
|
||||
$opt = $smarty->opt();
|
||||
|
||||
session_start();
|
||||
if (!isset($_SESSION["userid"])) {
|
||||
header("Location: " . getFullPath("login.php") . "?from=help.php");
|
||||
exit;
|
||||
}
|
||||
else {
|
||||
$userid = $_SESSION["userid"];
|
||||
}
|
||||
|
||||
$action = "";
|
||||
if (!empty($_POST["action"])) {
|
||||
$action = $_POST["action"];
|
||||
|
||||
if ($action == "save") {
|
||||
if (!empty($_POST["show_helptext"]))
|
||||
$show_helptext = ($_POST["show_helptext"] == "on" ? 1 : 0);
|
||||
else
|
||||
$show_helptext = 0;
|
||||
|
||||
try {
|
||||
$stmt = $smarty->dbh()->prepare("UPDATE {$opt["table_prefix"]}users SET show_helptext = ? WHERE userid = ?");
|
||||
$stmt->bindParam(1, $show_helptext, PDO::PARAM_BOOL);
|
||||
$stmt->bindParam(2, $userid, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
die("sql exception: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
die("Unknown verb.");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $smarty->dbh()->prepare("SELECT show_helptext FROM {$opt["table_prefix"]}users WHERE userid = ?");
|
||||
$stmt->bindParam(1, $userid, PDO::PARAM_INT);
|
||||
|
||||
$stmt->execute();
|
||||
if ($row = $stmt->fetch()) {
|
||||
$smarty->assign('show_helptext', $row["show_helptext"]);
|
||||
$_SESSION['show_helptext'] = $row["show_helptext"];
|
||||
}
|
||||
else {
|
||||
die("You don't exist.");
|
||||
}
|
||||
}
|
||||
catch (PDOException $e) {
|
||||
die("sql exception: " . $e->getMessage());
|
||||
}
|
||||
|
||||
$smarty->assign('myurl', "{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}");
|
||||
$smarty->display('help.tpl');
|
||||
|
||||
?>
|
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 701 B |
Before Width: | Height: | Size: 698 B |
Before Width: | Height: | Size: 718 B |
Before Width: | Height: | Size: 724 B |
Before Width: | Height: | Size: 687 B |
Before Width: | Height: | Size: 6 KiB |
Before Width: | Height: | Size: 854 B |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 736 B |
Before Width: | Height: | Size: 6 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 972 B |
Before Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1,013 B |
Before Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 845 B |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 20 KiB |
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
|
||||
define('SMARTY_DIR', dirname(__FILE__) . "/smarty-5.4.1/libs/");
|
||||
define('SMARTY_DIR', dirname(__FILE__) . "/smarty-3.1.48/libs/");
|
||||
require_once(SMARTY_DIR . "Smarty.class.php");
|
||||
require_once(dirname(__FILE__) . "/config.php");
|
||||
|
||||
class MySmarty extends Smarty\Smarty {
|
||||
class MySmarty extends Smarty {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
|
@ -19,12 +19,11 @@ class MySmarty extends Smarty\Smarty {
|
|||
$opt["pdo_password"]);
|
||||
}
|
||||
|
||||
public function opt($session = NULL) {
|
||||
public function opt() {
|
||||
static $opt;
|
||||
if (!isset($opt)) {
|
||||
$opt = getGlobalOptions();
|
||||
}
|
||||
$opt['show_helptext'] = isset($_SESSION['show_helptext']) ? $_SESSION['show_helptext'] : $opt['show_helptext'];
|
||||
return $opt;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,32 +14,15 @@
|
|||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
function getGlobalOptions() {
|
||||
// Read information
|
||||
$conf_file = '/var/www/conf/phpgiftreg.conf';
|
||||
$mysql_conn_string = "mysql:host=localhost;dbname=giftreg";
|
||||
$mysql_username = "giftreg";
|
||||
$mysql_password = "cn3Malk";
|
||||
if (file_exists($conf_file)) {
|
||||
$ini_file = parse_ini_file($conf_file);
|
||||
if (isset($ini_file['mysql_conn_string'])) {
|
||||
$mysql_conn_string = $ini_file['mysql_conn_string'];
|
||||
}
|
||||
if (isset($ini_file['mysql_username'])) {
|
||||
$mysql_username = $ini_file['mysql_username'];
|
||||
}
|
||||
if (isset($ini_file['mysql_password'])) {
|
||||
$mysql_password = $ini_file['mysql_password'];
|
||||
}
|
||||
}
|
||||
return array(
|
||||
/* The PDO connection string.
|
||||
http://www.php.net/manual/en/pdo.connections.php
|
||||
*/
|
||||
"pdo_connection_string" => $mysql_conn_string,
|
||||
"pdo_connection_string" => "mysql:host=localhost;dbname=giftreg",
|
||||
|
||||
/* The database username and password. */
|
||||
"pdo_username" => $mysql_username,
|
||||
"pdo_password" => $mysql_password,
|
||||
"pdo_username" => "giftreg",
|
||||
"pdo_password" => "cn3Malk",
|
||||
|
||||
/* The maximum number of days before an event which produces a notification. */
|
||||
"event_threshold" => "60",
|
||||
|
@ -48,7 +31,7 @@ function getGlobalOptions() {
|
|||
0 = auto-approve,
|
||||
1 = require approval
|
||||
*/
|
||||
"shop_requires_approval" => 0,
|
||||
"shop_requires_approval" => 1,
|
||||
|
||||
/* Whether or not requesting a new account is immediately approved.
|
||||
0 = auto-approve,
|
||||
|
@ -56,12 +39,6 @@ function getGlobalOptions() {
|
|||
*/
|
||||
"newuser_requires_approval" => 1,
|
||||
|
||||
/* Do not allow new user to choose family
|
||||
0 = allow new user to choose family
|
||||
1 or more = default family
|
||||
*/
|
||||
"newuser_default_family" => 1,
|
||||
|
||||
/* Whether or not whom an item is reserved/bought by is hidden. */
|
||||
"anonymous_purchasing" => 0,
|
||||
|
||||
|
@ -69,30 +46,27 @@ function getGlobalOptions() {
|
|||
"items_per_page" => 10,
|
||||
|
||||
/* The e-mail From: header. */
|
||||
"email_from" => "wishlist@erdelynet.com",
|
||||
"email_from" => "webmaster@" . $_SERVER['SERVER_NAME'],
|
||||
|
||||
/* The e-mail Reply-To: header. */
|
||||
"email_reply_to" => "wishlist@erdelynet.com",
|
||||
"email_reply_to" => "rwalberg@mts.net",
|
||||
|
||||
/* The e-mail X-Mailer header. */
|
||||
"email_xmailer" => "PHP/" . phpversion(),
|
||||
|
||||
/* Application name. */
|
||||
"app_name" => "Gift Wishlist",
|
||||
|
||||
/* Whether or not to show brief blurbs in certain spots which describe how
|
||||
features work.
|
||||
0 = don't help text,
|
||||
1 = show help text
|
||||
*/
|
||||
"show_helptext" => 1,
|
||||
"show_helptext" => 0,
|
||||
|
||||
/* Whether or not clicking the Delete Item link requires a JavaScript-based
|
||||
confirmation.
|
||||
0 = don't show confirmation,
|
||||
1 = show confirmation
|
||||
*/
|
||||
"confirm_item_deletes" => 1,
|
||||
"confirm_item_deletes" => 0,
|
||||
|
||||
/* Whether or not to allow multiple quantities of an item. */
|
||||
"allow_multiples" => 1,
|
||||
|
@ -128,39 +102,7 @@ function getGlobalOptions() {
|
|||
0 = don't hide it,
|
||||
1 = hide it
|
||||
*/
|
||||
"hide_zero_price" => 0,
|
||||
|
||||
/* Default raking
|
||||
This is the default rankings list:
|
||||
5 = I'd love to get this
|
||||
4 = I would really, really like this
|
||||
3 = Would make me happy
|
||||
2 = Would be nice to have
|
||||
1 = Wouldn't mind it
|
||||
*/
|
||||
"default_ranking" => 3,
|
||||
|
||||
/* Default category
|
||||
This is the default categories list:
|
||||
1 = Miscellaneous
|
||||
2 = Music
|
||||
3 = Video Games
|
||||
4 = Clothing
|
||||
5 = Movies/DVD
|
||||
6 = Gift Certificates
|
||||
7 = Hobbies
|
||||
8 = Household
|
||||
9 = Electronics
|
||||
10 = Ornaments/Figurines
|
||||
11 = Automotive
|
||||
12 = Toys
|
||||
13 = Jewelry
|
||||
14 = Computer
|
||||
15 = Games
|
||||
16 = Tools
|
||||
17 = Books
|
||||
*/
|
||||
"default_category" => 1,
|
||||
"hide_zero_price" => 1,
|
||||
|
||||
/* Whether or not to hash passwords. Your version of MySQL may or may not
|
||||
support it.
|
||||
|
@ -171,7 +113,7 @@ function getGlobalOptions() {
|
|||
UPDATE users SET password = MD5(password)
|
||||
on your database to convert the passwords. This operation is NON-REVERSIBLE!
|
||||
*/
|
||||
"password_hasher" => "SHA1",
|
||||
"password_hasher" => "MD5",
|
||||
|
||||
/* Whether or not to allow image uploads. If on, the next option must point to
|
||||
a valid subdirectory that is writeable by the web server. The setup.php
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
<?php
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
function getGlobalOptions() {
|
||||
return array(
|
||||
/* The PDO connection string.
|
||||
http://www.php.net/manual/en/pdo.connections.php
|
||||
*/
|
||||
"pdo_connection_string" => "mysql:host=localhost;dbname=giftreg",
|
||||
|
||||
/* The database username and password. */
|
||||
"pdo_username" => "giftreg",
|
||||
"pdo_password" => "cn3Malk",
|
||||
|
||||
/* The maximum number of days before an event which produces a notification. */
|
||||
"event_threshold" => "60",
|
||||
|
||||
/* Whether or not requesting to shop for someone is immediately approved.
|
||||
0 = auto-approve,
|
||||
1 = require approval
|
||||
*/
|
||||
"shop_requires_approval" => 1,
|
||||
|
||||
/* Whether or not requesting a new account is immediately approved.
|
||||
0 = auto-approve,
|
||||
1 = require administrator approval
|
||||
*/
|
||||
"newuser_requires_approval" => 1,
|
||||
|
||||
/* Whether or not whom an item is reserved/bought by is hidden. */
|
||||
"anonymous_purchasing" => 0,
|
||||
|
||||
/* The number of your items that show on each page. */
|
||||
"items_per_page" => 10,
|
||||
|
||||
/* The e-mail From: header. */
|
||||
"email_from" => "webmaster@" . $_SERVER['SERVER_NAME'],
|
||||
|
||||
/* The e-mail Reply-To: header. */
|
||||
"email_reply_to" => "rwalberg@mts.net",
|
||||
|
||||
/* The e-mail X-Mailer header. */
|
||||
"email_xmailer" => "PHP/" . phpversion(),
|
||||
|
||||
/* Whether or not to show brief blurbs in certain spots which describe how
|
||||
features work.
|
||||
0 = don't help text,
|
||||
1 = show help text
|
||||
*/
|
||||
"show_helptext" => 0,
|
||||
|
||||
/* Whether or not clicking the Delete Item link requires a JavaScript-based
|
||||
confirmation.
|
||||
0 = don't show confirmation,
|
||||
1 = show confirmation
|
||||
*/
|
||||
"confirm_item_deletes" => 0,
|
||||
|
||||
/* Whether or not to allow multiple quantities of an item. */
|
||||
"allow_multiples" => 1,
|
||||
|
||||
/* This is prefixed to all currency values, set it as appropriate for your currency. */
|
||||
"currency_symbol" => "$", // US or other dollars
|
||||
//"currency_symbol" => "£", // Pound (£) symbol
|
||||
//"currency_symbol" => "¥", // Yen
|
||||
//"currency_symbol" => "€", // Euro
|
||||
//"currency_symbol" => "€", // Euro alternative
|
||||
|
||||
/* The date format used in DateTime::format()
|
||||
http://php.net/manual/en/function.date.php */
|
||||
"date_format" => "m/d/Y",
|
||||
|
||||
/* If this is set to something other than "" then phpgiftreg will expect that
|
||||
string to prefix all tables in this installation. Useful for running
|
||||
multiple phpgiftreg installations in the same MySQL database.
|
||||
*/
|
||||
"table_prefix" => "",
|
||||
//"table_prefix" => "gift_", // all tables must be prefixed by `gift_'
|
||||
|
||||
/* Whether or not your own events show up on the home page.
|
||||
0 = don't show my own events,
|
||||
1 = show my own events
|
||||
*/
|
||||
"show_own_events" => 1,
|
||||
|
||||
/* The length of random generated passwords. */
|
||||
"password_length" => 8,
|
||||
|
||||
/* Whether or not to hide the price when it's $0.00.
|
||||
0 = don't hide it,
|
||||
1 = hide it
|
||||
*/
|
||||
"hide_zero_price" => 1,
|
||||
|
||||
/* Whether or not to hash passwords. Your version of MySQL may or may not
|
||||
support it.
|
||||
"MD5" = use MySQL's MD5() function,
|
||||
"SHA1" = use MySQL's SHA1() function,
|
||||
"" = use nothing (store passwords in plaintext).
|
||||
If you switch this on, you're going to need to do a
|
||||
UPDATE users SET password = MD5(password)
|
||||
on your database to convert the passwords. This operation is NON-REVERSIBLE!
|
||||
*/
|
||||
"password_hasher" => "MD5",
|
||||
|
||||
/* Whether or not to allow image uploads. If on, the next option must point to
|
||||
a valid subdirectory that is writeable by the web server. The setup.php
|
||||
script will confirm this.
|
||||
0 = don't allow images,
|
||||
1 = allow images
|
||||
*/
|
||||
"allow_images" => 1,
|
||||
|
||||
/* The *sub*-directory we we can store item images. If you don't want to
|
||||
allow images to be attached to items, leave this variable empty ("").
|
||||
Trailing / is optional.
|
||||
*/
|
||||
"image_subdir" => "item_images",
|
||||
|
||||
/* The number of minutes in between subscription notifications so the subscribers
|
||||
don't get flooded with updates.
|
||||
*/
|
||||
"notify_threshold_minutes" => 60
|
||||
);
|
||||
}
|
||||
?>
|
|
@ -6,265 +6,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [5.4.1] - 2024-08-29
|
||||
|
||||
|
||||
- Enable (and fix) unit tests for Windows [#1046](https://github.com/smarty-php/smarty/pull/1046)
|
||||
- Fix the use of "extends:" to define the inheritance tree on Windows [#1018](https://github.com/smarty-php/smarty/issues/1018)
|
||||
|
||||
## [5.4.0] - 2024-08-14
|
||||
- Fixing forced OpCache invalidation on every template include, which is resulting in fast raising wasted OpCache memory [#1007](https://github.com/smarty-php/smarty/issues/1007)
|
||||
- Improvement of auto-escaping [#1030](https://github.com/smarty-php/smarty/pull/1030)
|
||||
|
||||
|
||||
## [5.3.1] - 2024-06-16
|
||||
- Fixed error when using section with nocache [#1034](https://github.com/smarty-php/smarty/issues/1034)
|
||||
|
||||
|
||||
## [5.3.0] - 2024-05-30
|
||||
- Fix warning when calling hasVariable for an undefined variable [#977](https://github.com/smarty-php/smarty/issues/977)
|
||||
- Added `$smarty->prependTemplateDir()` method [#1022](https://github.com/smarty-php/smarty/issues/1022)
|
||||
|
||||
|
||||
## [5.2.0] - 2024-05-28
|
||||
- Fixed a code injection vulnerability in extends-tag. This addresses CVE-2024-35226.
|
||||
- Added `$smarty->setCacheModifiedCheck()` setter for cache_modified_check
|
||||
- Added a PSR-4 loading script to allow Smarty to be used without Composer [#1017](https://github.com/smarty-php/smarty/pull/1017)
|
||||
|
||||
|
||||
## [5.1.0] - 2024-04-22
|
||||
- Prevent deprecation notices during compilation in PHP8.3 [#996](https://github.com/smarty-php/smarty/issues/996)
|
||||
- Fix that getTemplateVars would return an array of objects instead of the assigned variables values [#994](https://github.com/smarty-php/smarty/issues/994)
|
||||
- Fix Smarty::assign() not returning $this when called with an array as first parameter [#972](https://github.com/smarty-php/smarty/pull/972)
|
||||
- Documented support for `{if $element is in $array}` syntax [#937](https://github.com/smarty-php/smarty/issues/937)
|
||||
- Added support for `{if $element is not in $array}` syntax [#937](https://github.com/smarty-php/smarty/issues/937)
|
||||
- Using stream variables in templates now throws a deprecation notice [#933](https://github.com/smarty-php/smarty/pull/933)
|
||||
- Internal compiler classes always return a string (the internal has_code flag has been removed for simplicity) [#918](https://github.com/smarty-php/smarty/pull/918)
|
||||
- Fix invalid classnames in Runtime code for foreach [#1000](https://github.com/smarty-php/smarty/issues/1000)
|
||||
|
||||
## [5.0.2] - 2024-03-28
|
||||
- Fix Smarty::assign() not returning $this when called with an array as first parameter [#972](https://github.com/smarty-php/smarty/pull/972)
|
||||
|
||||
## [5.0.1] - 2024-03-27
|
||||
- Fix error in Smarty\Smarty::compileAllTemplates() by including missing FilesystemIterator class [#966](https://github.com/smarty-php/smarty/issues/966)
|
||||
|
||||
## [5.0.0] - 2024-03-25
|
||||
- Fixed that scoped variables would overwrite parent scope [#952](https://github.com/smarty-php/smarty/issues/952)
|
||||
- Removed publicly accessible `$tpl->_var_stack` variable
|
||||
|
||||
### Fixed
|
||||
- Too many shorthand attributes error when using a modifier as a function with more than 3 parameters in an expression [#949](https://github.com/smarty-php/smarty/issues/949)
|
||||
|
||||
### Removed
|
||||
- Dropped support for undocumented `{time()}` added in v5.0.0 since we already have the documented `{$smarty.now}`
|
||||
|
||||
## [5.0.0-rc3] - 2024-02-26
|
||||
|
||||
### Added
|
||||
- PHP8.3 support [#925](https://github.com/smarty-php/smarty/issues/925)
|
||||
- Backlink to GitHub in docs
|
||||
- Explain how to do escaping and set-up auto-escaping in docs [#865](https://github.com/smarty-php/smarty/issues/865)
|
||||
- Link to variable scope page in the documentation for the assign tag [#878](https://github.com/smarty-php/smarty/issues/878)
|
||||
- Add support for implode, substr and json_encode as modifiers/functions in templates [#939](https://github.com/smarty-php/smarty/issues/939)
|
||||
- Add template path to CompilerException to enable rich debug features [#935](https://github.com/smarty-php/smarty/issues/935)
|
||||
|
||||
### Fixed
|
||||
- The {debug} tag was broken in v5 [#922](https://github.com/smarty-php/smarty/issues/922)
|
||||
- Documentation on `{if $x is even by $y}` syntax
|
||||
- Fix incorrect compilation of expressions when escape_html=true [#930](https://github.com/smarty-php/smarty/pull/930)
|
||||
|
||||
## [5.0.0-rc2] - 2023-11-11
|
||||
|
||||
### Fixed
|
||||
- Registered output filters wouldn't run [#899](https://github.com/smarty-php/smarty/issues/899)
|
||||
- Use of negative numbers in {math} equations [#895](https://github.com/smarty-php/smarty/issues/895)
|
||||
- Do not auto-html-escape custom function results [#906](https://github.com/smarty-php/smarty/issues/906)
|
||||
- Fix case-sensitive tag names [#907](https://github.com/smarty-php/smarty/issues/907)
|
||||
|
||||
### Removed
|
||||
- Removed `$smarty->registered_filters` array
|
||||
|
||||
## [5.0.0-rc1] - 2023-08-08
|
||||
|
||||
### Added
|
||||
- Added support for PHP8.2
|
||||
- Added a new way to extend Smarty functionality using `Smarty::addExtension()` or `Smarty::setExtensions()`. Please see the docs for more information.
|
||||
- Custom tags can accept positional parameters, so you can write a block compiler that support this: `{trans "Jack" "dull boy"}All work and no play makes %s a %s.{/trans}` [#164](https://github.com/smarty-php/smarty/issues/164)
|
||||
- Full support for ternary operator: `{$test ? $a : $b}` and `{$var ?: $value_if_falsy}` [#881](https://github.com/smarty-php/smarty/issues/881)
|
||||
- Full support for null coalescing operator: `{$var ?? $value_if_null}` [#882](https://github.com/smarty-php/smarty/issues/882)
|
||||
|
||||
### Changed
|
||||
- All Smarty code is now in the \Smarty namespace. For simple use-cases, you only need to add
|
||||
`use \Smarty\Smarty;` to your script and everything will work. If you extend Smarty or use
|
||||
Smarty plug-ins, please review your code to see if they assume specific class or method names.
|
||||
E.g.: `Smarty_Internal_Template` is now `\Smarty\Template\`, `SmartyException` is now `\Smarty\Exception`.
|
||||
- Template variable scope bubbling has been simplified and made more consistent.
|
||||
The global scope now equals the Smarty scope in order to avoid global state side effects. Please read
|
||||
the documentation for more details.
|
||||
- Lexers and Parsers PHP files are reliably generated from sources (.y and .plex) using the make file
|
||||
- Smarty now always runs in multibyte mode, using `symfony/polyfill-mbstring` if required. Please use the
|
||||
multibyte extension for optimal performance.
|
||||
- Smarty no longer calls `mb_internal_encoding()` and doesn't check for deprecated `mbstring.func_overload` ini directive [#480](https://github.com/smarty-php/smarty/issues/480)
|
||||
- Generated `<script>` tags lo longer have deprecated `type="text/javascript"` or `language="Javascript"` attributes [#815](https://github.com/smarty-php/smarty/issues/815)
|
||||
- Smarty will throw a compiler exception instead of silently ignoring a modifier on a function call, like this: `{include|dot:"x-template-id" file="included.dot.tpl"}` [#526](https://github.com/smarty-php/smarty/issues/526)
|
||||
- The documentation was largely rewritten
|
||||
|
||||
### Deprecated
|
||||
- `$smarty->getPluginsDir()`
|
||||
- `$smarty->loadFilter()`
|
||||
- `$smarty->setPluginsDir()`
|
||||
- `$smarty->assignGlobal()`
|
||||
- Using `$smarty->registerFilter()` for registering variable filters will trigger a notice.
|
||||
|
||||
### Removed
|
||||
- Dropped support for PHP7.1
|
||||
- Removed `$smarty->left_delimiter` and `$smarty->right_delimiter`, use `$smarty->getLeftDelimiter()`/`$smarty->setLeftDelimiter()` and `$smarty->getRightDelimiter()`/`$smarty->setRightDelimiter()`
|
||||
- Removed support for the `$cache_attrs` parameter for registered plugins
|
||||
- Removed support for undocumented `{make_nocache}` tag
|
||||
- Removed support for deprecated `{insert}` tag, the 'insert' plugin type and the associated $smarty->trusted_dir variable
|
||||
- Removed the undocumented `{block_parent}` and `{parent}` alternatives to `{$smarty.block.parent}`
|
||||
- Removed the undocumented `{block_child}` and `{child}` alternatives to `{$smarty.block.child}`
|
||||
- Removed support for loading config files into a non-local scope using `{config_load}` from a template
|
||||
- Removed `$smarty->autoload_filters` in favor of `$smarty->registerFilter()`
|
||||
- Removed `$smarty->trusted_dir` and `$smarty->allow_php_templates` since support for executing php scripts from templates has been dropped
|
||||
- Removed `$smarty->php_functions` and `$smarty->php_modifiers`.
|
||||
- You can no longer use native PHP-functions or userland functions in your templates without registering them. If you need a function in your templates,
|
||||
register it first.
|
||||
- Removed support for `$smarty->getTags()`
|
||||
- Removed the abandoned `$smarty->direct_access_security` setting
|
||||
- Dropped support for `$smarty->plugins_dir` and `$smarty->use_include_path`. If you must, use `$smarty->addPluginsDir()` instead,
|
||||
but it's better to use Smarty::addExtension() to add an extension or Smarty::registerPlugin to
|
||||
quickly register a plugin using a callback function.
|
||||
- Removed constants such as SMARTY_DIR to prevent global side effects.
|
||||
- Removed direct access to `$smarty->template_dir`. Use `$smarty->setTemplateDir()`.
|
||||
- Removed direct access to `$smarty->cache_dir`. Use `$smarty->setCacheDir()`.
|
||||
- Removed direct access to `$smarty->compile_dir`. Use `$smarty->setCompileDir()`.
|
||||
- Removed `$smarty->loadPlugin()`, use `$smarty->registerPlugin()` instead.
|
||||
- Removed `$smarty->appendByRef()` and `$smarty->assignByRef()`.
|
||||
- Removed `$smarty->_current_file`
|
||||
- Removed `$smarty->allow_ambiguous_resources` (ambiguous resources handlers should still work)
|
||||
|
||||
### Fixed
|
||||
- `|strip_tags` does not work if the input is 0 [#890](https://github.com/smarty-php/smarty/issues/890)
|
||||
|
||||
## [4.3.2] - 2023-07-19
|
||||
|
||||
### Fixed
|
||||
- `$smarty->muteUndefinedOrNullWarnings()` now also mutes PHP8 warnings for undefined properties
|
||||
|
||||
## [4.3.1] - 2023-03-28
|
||||
## [3.1.48] - 2023-03-28
|
||||
|
||||
### Security
|
||||
- Fixed Cross site scripting vulnerability in Javascript escaping. This addresses CVE-2023-28447.
|
||||
- Fixed Cross site scripting vulnerability in Javascript escaping. This addresses CVE-2023-28447.
|
||||
|
||||
### Fixed
|
||||
- `$smarty->muteUndefinedOrNullWarnings()` now also mutes PHP7 notices for undefined array indexes [#736](https://github.com/smarty-php/smarty/issues/736)
|
||||
- `$smarty->muteUndefinedOrNullWarnings()` now treats undefined vars and array access of a null or false variables
|
||||
equivalent across all supported PHP versions
|
||||
- `$smarty->muteUndefinedOrNullWarnings()` now allows dereferencing of non-objects across all supported PHP versions [#831](https://github.com/smarty-php/smarty/issues/831)
|
||||
- PHP 8.1 deprecation warnings on null strings in modifiers [#834](https://github.com/smarty-php/smarty/pull/834)
|
||||
|
||||
## [4.3.0] - 2022-11-22
|
||||
|
||||
### Added
|
||||
- PHP8.2 compatibility [#775](https://github.com/smarty-php/smarty/pull/775)
|
||||
|
||||
### Changed
|
||||
- Include docs and demo in the releases [#799](https://github.com/smarty-php/smarty/issues/799)
|
||||
- Using PHP functions as modifiers now triggers a deprecation notice because we will drop support for this in the next major release [#813](https://github.com/smarty-php/smarty/issues/813)
|
||||
- Dropped remaining references to removed PHP-support in Smarty 4 from docs, lexer and security class. [#816](https://github.com/smarty-php/smarty/issues/816)
|
||||
- Support umask when writing (template) files and set dir permissions to 777 [#548](https://github.com/smarty-php/smarty/issues/548) [#819](https://github.com/smarty-php/smarty/issues/819)
|
||||
|
||||
### Fixed
|
||||
- Output buffer is now cleaned for internal PHP errors as well, not just for Exceptions [#514](https://github.com/smarty-php/smarty/issues/514)
|
||||
- Fixed recursion and out of memory errors when caching in complicated template set-ups using inheritance and includes [#801](https://github.com/smarty-php/smarty/pull/801)
|
||||
- Fixed PHP8.1 deprecation errors in strip_tags
|
||||
- Fix Variable Usage in Exception message when unable to load subtemplate [#808](https://github.com/smarty-php/smarty/pull/808)
|
||||
- Fixed PHP8.1 deprecation notices for strftime [#672](https://github.com/smarty-php/smarty/issues/672)
|
||||
- Fixed PHP8.1 deprecation errors passing null to parameter in trim [#807](https://github.com/smarty-php/smarty/pull/807)
|
||||
- Adapt Smarty upper/lower functions to be codesafe (e.g. for Turkish locale) [#586](https://github.com/smarty-php/smarty/pull/586)
|
||||
- Bug fix for underscore and limited length in template name in custom resources [#581](https://github.com/smarty-php/smarty/pull/581)
|
||||
|
||||
## [4.2.1] - 2022-09-14
|
||||
## [3.1.47] - 2022-09-14
|
||||
|
||||
### Security
|
||||
- Applied appropriate javascript and html escaping in mailto plugin to counter injection attacks [#454](https://github.com/smarty-php/smarty/issues/454)
|
||||
|
||||
### Fixed
|
||||
- Fixed PHP8.1 deprecation notices in modifiers (upper, explode, number_format and replace) [#755](https://github.com/smarty-php/smarty/pull/755) and [#788](https://github.com/smarty-php/smarty/pull/788)
|
||||
- Fixed PHP8.1 deprecation notices in capitalize modifier [#789](https://github.com/smarty-php/smarty/issues/789)
|
||||
- Fixed use of `rand()` without a parameter in math function [#794](https://github.com/smarty-php/smarty/issues/794)
|
||||
- Fixed unselected year/month/day not working in html_select_date [#395](https://github.com/smarty-php/smarty/issues/395)
|
||||
|
||||
## [4.2.0] - 2022-08-01
|
||||
- Updated requirement contraint for 'php' in composer.json to correctly reflect that Smarty3 does not support PHP8. Please upgrade to Smarty4 to use PHP8.
|
||||
|
||||
## [3.1.46] - 2022-08-01
|
||||
|
||||
### Fixed
|
||||
- Fixed problems with smarty_mb_str_replace [#549](https://github.com/smarty-php/smarty/issues/549)
|
||||
- Fixed second parameter of unescape modifier not working [#777](https://github.com/smarty-php/smarty/issues/777)
|
||||
|
||||
### Changed
|
||||
- Updated HTML of the debug template [#599](https://github.com/smarty-php/smarty/pull/599)
|
||||
|
||||
## [4.1.1] - 2022-05-17
|
||||
## [3.1.45] - 2022-05-17
|
||||
|
||||
### Security
|
||||
- Prevent PHP injection through malicious block name or include file name. This addresses CVE-2022-29221
|
||||
|
||||
### Fixed
|
||||
- Exclude docs and demo from export and composer [#751](https://github.com/smarty-php/smarty/pull/751)
|
||||
- PHP 8.1 deprecation notices in demo/plugins/cacheresource.pdo.php [#706](https://github.com/smarty-php/smarty/issues/706)
|
||||
- PHP 8.1 deprecation notices in truncate modifier [#699](https://github.com/smarty-php/smarty/issues/699)
|
||||
- Math equation `max(x, y)` didn't work anymore [#721](https://github.com/smarty-php/smarty/issues/721)
|
||||
- Fix PHP 8.1 deprecated warning when calling rtrim [#743](https://github.com/smarty-php/smarty/pull/743)
|
||||
- PHP 8.1: fix deprecation in escape modifier [#727](https://github.com/smarty-php/smarty/pull/727)
|
||||
|
||||
## [4.1.0] - 2022-02-06
|
||||
|
||||
### Added
|
||||
- PHP8.1 compatibility [#713](https://github.com/smarty-php/smarty/pull/713)
|
||||
|
||||
## [4.0.4] - 2022-01-18
|
||||
## [3.1.44] - 2022-01-18
|
||||
|
||||
### Fixed
|
||||
- Fixed illegal characters bug in math function security check [#702](https://github.com/smarty-php/smarty/issues/702)
|
||||
|
||||
## [4.0.3] - 2022-01-10
|
||||
## [3.1.43] - 2022-01-10
|
||||
|
||||
### Security
|
||||
- Prevent evasion of the `static_classes` security policy. This addresses CVE-2021-21408
|
||||
|
||||
## [4.0.2] - 2022-01-10
|
||||
## [3.1.42] - 2022-01-10
|
||||
|
||||
### Security
|
||||
- Prevent arbitrary PHP code execution through maliciously crafted expression for the math function. This addresses CVE-2021-29454
|
||||
|
||||
## [4.0.1] - 2022-01-09
|
||||
## [3.1.41] - 2022-01-09
|
||||
|
||||
### Security
|
||||
- Rewrote the mailto function to not use `eval` when encoding with javascript
|
||||
|
||||
## [4.0.0] - 2021-11-25
|
||||
|
||||
## [4.0.0-rc.0] - 2021-10-13
|
||||
|
||||
### Added
|
||||
- You can now use `$smarty->muteUndefinedOrNullWarnings()` to activate convert warnings about undefined or null template vars to notices when running PHP8
|
||||
|
||||
### Changed
|
||||
- Switch CI from Travis to Github CI
|
||||
- Updated unit tests to avoid skipped and risky test warnings
|
||||
|
||||
### Removed
|
||||
- Dropped support for PHP7.0 and below, so Smarty now requires PHP >=7.1
|
||||
- Dropped support for php asp tags in templates (removed from php since php7.0)
|
||||
- Dropped deprecated API calls that where only accessible through SmartyBC
|
||||
- Dropped support for {php} and {include_php} tags and embedded PHP in templates. Embedded PHP will now be passed through as is.
|
||||
- Removed all PHP_VERSION_ID and compare_version checks and conditional code blocks that are now no longer required
|
||||
- Dropped deprecated SMARTY_RESOURCE_CHAR_SET and SMARTY_RESOURCE_DATE_FORMAT constants
|
||||
- Dropped deprecated Smarty::muteExpectedErrors and Smarty::unmuteExpectedErrors API methods
|
||||
- Dropped deprecated $smarty->getVariable() method. Use $smarty->getTemplateVars() instead.
|
||||
- $smarty->registerResource() no longer accepts an array of callback functions
|
||||
|
||||
## [3.1.40] - 2021-10-13
|
||||
|
||||
### Changed
|
||||
|
@ -1928,7 +1721,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
27.09.2011
|
||||
- bugfix possible warning "attempt to modify property of non-object" in {section} (issue #34)
|
||||
- added chaining to \Smarty\Data so $smarty->assign('a',1)->assign('b',2); is possible now
|
||||
- added chaining to Smarty_Internal_Data so $smarty->assign('a',1)->assign('b',2); is possible now
|
||||
- bugfix remove race condition when a custom resource did change timestamp during compilation
|
||||
- bugfix variable property did not work on objects variable in template
|
||||
- bugfix smarty_make_timestamp() failed to process DateTime objects properly
|
||||
|
@ -2263,7 +2056,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- optimize smarty_modified_escape for hex, hexentity, decentity.
|
||||
|
||||
28/12/2010
|
||||
- changed $tpl_vars, $config_vars and $parent to belong to \Smarty\Data
|
||||
- changed $tpl_vars, $config_vars and $parent to belong to Smarty_Internal_Data
|
||||
- added Smarty::registerCacheResource() for dynamic cache resource object registration
|
||||
|
||||
27/12/2010
|
31
src/includes/smarty-3.1.48/COMPOSER_RELEASE_NOTES.txt
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
|
||||
Starting with Smarty 3.1.21 Composer has been configured to load the packages from github.
|
||||
|
||||
*******************************************************************************
|
||||
* *
|
||||
* NOTE: Because of this change you must clear your local composer cache with *
|
||||
* the "composer clearcache" command *
|
||||
* *
|
||||
*******************************************************************************
|
||||
|
||||
To get the latest stable version use
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1"
|
||||
}
|
||||
in your composer.json file.
|
||||
|
||||
To get the trunk version use
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1@dev"
|
||||
}
|
||||
|
||||
The "smarty/smarty" package will start at libs/.... subfolder.
|
||||
|
||||
To retrieve the development and documentation folders add
|
||||
"require-dev": {
|
||||
"smarty/smarty-dev": "~3.1@dev"
|
||||
}
|
||||
|
||||
If you are using (include) the composer generated autoloader.php which is located
|
||||
in the /vendor folder it is no longer needed to require the Smarty.class.php file.
|
91
src/includes/smarty-3.1.48/INHERITANCE_RELEASE_NOTES.txt
Normal file
|
@ -0,0 +1,91 @@
|
|||
3.1.3"
|
||||
New tags for inheritance parent and chilD
|
||||
{parent} == {$smarty.block.parent}
|
||||
{child} == {$smarty.block.child}
|
||||
Both tags support the assign attribute like
|
||||
{child assign=foo}
|
||||
|
||||
3.1.31
|
||||
New tags for inheritance parent and child
|
||||
{block_parent} == {$smarty.block.parent}
|
||||
{block_child} == {$smarty.block.child}
|
||||
|
||||
Since 3.1.28 you can mix inheritance by extends resource with the {extends} tag.
|
||||
A template called by extends resource can extend a subtemplate or chain buy the {extends} tag.
|
||||
Since 3.1.31 this feature can be turned off by setting the new Smarty property Smarty::$extends_recursion to false.
|
||||
|
||||
3.1.28
|
||||
Starting with version 3.1.28 template inheritance is no longer a compile time process.
|
||||
All {block} tag parent/child relations are resolved at run time.
|
||||
This does resolve all known existing restrictions (see below).
|
||||
|
||||
The $smarty::$inheritance_merge_compiled_includes property has been removed.
|
||||
Any access to it is ignored.
|
||||
|
||||
New features:
|
||||
|
||||
Any code outside root {block} tags in child templates is now executed but any output will be ignored.
|
||||
|
||||
{extends 'foo.tpl'}
|
||||
{$bar = 'on'} // assigns variable $bar seen in parent templates
|
||||
{block 'buh'}{/block}
|
||||
|
||||
{extends 'foo.tpl'}
|
||||
{$bar} // the output of variable bar is ignored
|
||||
{block 'buh'}{/block}
|
||||
|
||||
{block} tags can be dynamically en/disabled by conditions.
|
||||
|
||||
{block 'root'}
|
||||
{if $foo}
|
||||
{block 'v1'}
|
||||
....
|
||||
{/block}
|
||||
{else}
|
||||
{block 'v1'}
|
||||
....
|
||||
{/block}
|
||||
{/if}
|
||||
{/block}
|
||||
|
||||
{block} tags can have variable names.
|
||||
|
||||
{block $foo}
|
||||
....
|
||||
{/block}
|
||||
|
||||
Starting with 3.1.28 you can mix inheritance by extends resource with the {extends} tag.
|
||||
A template called by extends resource can extend a subtemplate or chain buy the {extends} tag.
|
||||
|
||||
NOTE There is a BC break. If you used the extends resource {extends} tags have been ignored.
|
||||
|
||||
THE FOLLOWING RESTRICTIONS ARE NO LONGER EXISTING:
|
||||
In Smarty 3.1 template inheritance is a compile time process. All the extending of {block} tags
|
||||
is done at compile time and the parent and child templates are compiled in a single compiled template.
|
||||
{include} subtemplate could also {block} tags. Such subtemplate could not compiled by it's own because
|
||||
it could be used in other context where the {block} extended with a different result. For that reasion
|
||||
the compiled code of {include} subtemplates gets also merged in compiled inheritance template.
|
||||
|
||||
Merging the code into a single compile template has some drawbacks.
|
||||
1. You could not use variable file names in {include} Smarty would use the {include} of compilation time.
|
||||
2. You could not use individual compile_id in {include}
|
||||
3. Separate caching of subtemplate was not possible
|
||||
4. Any change of the template directory structure between calls was not necessarily seen.
|
||||
|
||||
Starting with 3.1.15 some of the above conditions got checked and resulted in an exception. It turned out
|
||||
that a couple of users did use some of above and now got exceptions.
|
||||
|
||||
To resolve this starting with 3.1.16 there is a new configuration parameter $inheritance_merge_compiled_includes.
|
||||
For most backward compatibility its default setting is true.
|
||||
With this setting all {include} subtemplate will be merge into the compiled inheritance template, but the above cases
|
||||
could be rejected by exception.
|
||||
|
||||
|
||||
If $smarty->inheritance_merge_compiled_includes = false; {include} subtemplate will not be merged.You must now manually merge all {include} subtemplate which do contain {block} tags. This is done by setting the "inline" option.
|
||||
{include file='foo.bar' inline}
|
||||
|
||||
1. In case of a variable file name like {include file=$foo inline} you must use the variable in a compile_id $smarty->compile_id = $foo;
|
||||
2. If you use individual compile_id in {include file='foo.tpl' compile_id=$bar inline} it must be used in the global compile_id as well $smarty->compile_id = $bar;
|
||||
3. If call templates with different template_dir configurations and a parent could same named child template from different folders
|
||||
you must make the folder name part of the compile_id.
|
||||
|
291
src/includes/smarty-3.1.48/NEW_FEATURES.txt
Normal file
|
@ -0,0 +1,291 @@
|
|||
|
||||
|
||||
This file contains a brief description of new features which have been added to Smarty 3.1
|
||||
|
||||
Smarty 3.1.33-dev
|
||||
Variable capture name in Smarty special variable
|
||||
================================================
|
||||
{$smarty.capture.$foo} can now be used to access the content of a named
|
||||
capture block
|
||||
|
||||
Smarty 3.1.32
|
||||
New tags for inheritance parent and child
|
||||
=========================================
|
||||
{parent} == {$smarty.block.parent}
|
||||
{child} == {$smarty.block.child}
|
||||
Both tags support the assign attribute like
|
||||
{child assign=foo}
|
||||
|
||||
Deprecate functions Smarty::muteExpectedErrors() and Smarty::unmuteExpectedErrors()
|
||||
===================================================================================
|
||||
These functions to start a special error handler are no longer needed as Smarty does
|
||||
no longer use error suppression like @filemtime().
|
||||
For backward compatibility the functions still can be called.
|
||||
|
||||
Using literals containing Smarty's left and right delimiter
|
||||
===========================================================
|
||||
New Methods
|
||||
$smarty->setLiterals(array $literals)
|
||||
$smarty->addLiterals(array $literals)
|
||||
to define literals containing Smarty delimiter. This can avoid the need for extreme usage
|
||||
of {literal} {/literal} tags.
|
||||
A) Treat '{{' and '}}' as literal
|
||||
If Smarty::$auto_literal is enabled
|
||||
{{ foo }}
|
||||
will be treated now as literal. (This does apply for any number of delimiter repeatations).
|
||||
However {{foo}} is not an literal but will be interpreted as a recursive Smarty tag.
|
||||
If you use
|
||||
$smarty->setLiterals(array('{{','}}'));
|
||||
{{foo}} is now a literal as well.
|
||||
NOTE: In the last example nested Smarty tags starting with '{{' or ending with '}}' will not
|
||||
work any longer, but this should be very very raw occouring restriction.
|
||||
B) Example 2
|
||||
Assume your delimiter are '<-' , '->' and '<--' , '-->' shall be literals
|
||||
$smarty->setLiterals(array('<--','-->'));
|
||||
|
||||
|
||||
The capture buffers can now be accessed as array
|
||||
================================================
|
||||
{capture name='foo'}
|
||||
bah
|
||||
{\capture}
|
||||
{capture name='buh'}
|
||||
blar
|
||||
{\capture}
|
||||
{foreach $smarty.capture as $name => $buffer}
|
||||
....
|
||||
{/foreach}
|
||||
|
||||
Smarty 3.1.31
|
||||
New tags for inheritance parent and child
|
||||
=========================================
|
||||
{block_parent} == {$smarty.block.parent}
|
||||
{block_child} == {$smarty.block.child}
|
||||
|
||||
Smarty 3.1.30
|
||||
|
||||
Loop optimization {foreach} and {section}
|
||||
=========================================
|
||||
Smarty does optimize the {foreach} and {section} loops by removing code for not needed loop
|
||||
properties.
|
||||
The compiler collects needed properties by scanning the current template for $item@property,
|
||||
$smarty.foreach.name.property and $smarty.section.name.property.
|
||||
The compiler does not know if additional properties will be needed outside the current template scope.
|
||||
Additional properties can be generated by adding them with the property attribute.
|
||||
|
||||
Example:
|
||||
index.tpl
|
||||
{foreach $from as $item properties=[iteration, index]}
|
||||
{include 'sub.tpl'}
|
||||
{$item.total}
|
||||
{/foreach}
|
||||
|
||||
sub.tpl
|
||||
{$item.index} {$item.iteration} {$item.total}
|
||||
|
||||
In above example code for the 'total' property is automatically generated as $item.total is used in
|
||||
index.tpl. Code for 'iteration' and 'index' must be added with properties=[iteration, index].
|
||||
|
||||
New tag {make_nocache}
|
||||
======================
|
||||
Syntax: {make_nocache $foo}
|
||||
|
||||
This tag makes a variable which does exists normally only while rendering the compiled template
|
||||
available in the cached template for use in not cached expressions.
|
||||
|
||||
Expample:
|
||||
{foreach from=$list item=item}
|
||||
<li>{$item.name} {make_nocache $item}{if $current==$item.id} ACTIVE{/if}</li>
|
||||
{/foreach}
|
||||
|
||||
The {foreach} loop is rendered while processing the compiled template, but $current is a nocache
|
||||
variable. Normally the {if $current==$item.id} would fail as the $item variable is unknown in the cached template. {make_nocache $item} does make the current $item value known in thee cached template.
|
||||
|
||||
{make_nocache} is ignored when caching is disabled or the variable does exists as nocache variable.
|
||||
|
||||
NOTE: if the variable value does contain objects these must have the __set_state method implemented.
|
||||
|
||||
|
||||
Scope Attributes
|
||||
================
|
||||
The scope handling has been updated to cover all cases of variable assignments in templates.
|
||||
|
||||
The tags {assign}, {append} direct assignments like {$foo = ...}, {$foo[...]= ...} support
|
||||
the following optional scope attributes:
|
||||
scope='parent' - the variable will be assigned in the current template and if the template
|
||||
was included by {include} the calling template
|
||||
scope='tpl_root' - the variable will be assigned in the outermost root template called by $smarty->display()
|
||||
or $smarty->fetch() and is bubbled up all {include} sub-templates to the current template.
|
||||
scope='smarty' - the variable will be assigned in the Smarty object and is bubbled up all {include} sub-templates
|
||||
to the current template.
|
||||
scope='global' - the variable will be assigned as Smarty object global variable and is bubbled up all {include}
|
||||
sub-templates to the current template.
|
||||
scope='root' - the variable will be assigned if a data object was used for variable definitions in the data
|
||||
object or in the Smarty object otherwise and is bubbled up all {include} sub-templates to the
|
||||
current template.
|
||||
scope='local' - this scope has only a meaning if the tag is called within a template {function}.
|
||||
The variable will be assigned in the local scope of the template function and the
|
||||
template which did call the template function.
|
||||
|
||||
|
||||
The {config_load} tag supports all of the above except the global scope.
|
||||
|
||||
The scope attribute can be used also with the {include} tag.
|
||||
Supported scope are parent, tpl_root, smarty, global and root.
|
||||
A scope used together with the {include} tag will cause that with some exceptions any variable
|
||||
assignment within that sub-template will update/assign the variable in other scopes according
|
||||
to the above rules. It does include also variables assigned by plugins, tags supporting the assign=foo attribute and direct assignments in {if} and {while} like {if $foo=$bar}.
|
||||
Excluded are the key and value variables of {foreach}, {for} loop variables , variables passed by attributes
|
||||
in {include} and direct increments/decrements like {$foo++}, {$foo--}
|
||||
|
||||
Note: The scopes should be used only to the extend really need. If a variable value assigned in an included
|
||||
sub-template should be returned to the calling sub-template just use {$foo='bar' scope='parent'}.
|
||||
Use scopes only with variables for which it's realy needed. Avoid general scope settings with the
|
||||
{include} tag as it can have a performance impact.
|
||||
|
||||
The {assign}, {append}, {config_load} and {$foo...=...} tags have a new option flag 'noscope'.Thi
|
||||
Example: {$foo='bar' noscope} This will assign $foo only in the current template and any scope settings
|
||||
at {include} is ignored.
|
||||
|
||||
|
||||
Caching
|
||||
=======
|
||||
Caching does now observe the template_dir setting and will create separate cache files if required
|
||||
|
||||
Compiled Templates
|
||||
==================
|
||||
The template_dir setting is now encoded in the uid of the file name.
|
||||
The content of the compiled template may depend on the template_dir search order
|
||||
{include .... inline} is used or $smarty->merge_compiled_includes is enabled
|
||||
|
||||
APC
|
||||
===
|
||||
If APC is enabled force an apc_compile_file() when compiled or cached template was updated
|
||||
|
||||
Smarty 3.1.28
|
||||
|
||||
OPCACHE
|
||||
=======
|
||||
Smarty does now invalidate automatically updated and cleared compiled or cached template files in OPCACHE.
|
||||
Correct operation is no longer dependent on OPCACHE configuration settings.
|
||||
|
||||
Template inheritance
|
||||
====================
|
||||
Template inheritance is now processed in run time.
|
||||
See the INHERITANCE_RELEASE_NOTES
|
||||
|
||||
Modifier regex_replace
|
||||
======================
|
||||
An optional limit parameter was added
|
||||
|
||||
fetch() and display()
|
||||
=====================
|
||||
The fetch() and display() methods of the template object accept now optionally the same parameter
|
||||
as the corresponding Smarty methods to get the content of another template.
|
||||
Example:
|
||||
$template->display(); Does display template of template object
|
||||
$template->display('foo.tpl'); Does display template 'foo.bar'
|
||||
|
||||
File: resource
|
||||
==============
|
||||
Multiple template_dir entries can now be selected by a comma separated list of indices.
|
||||
The template_dir array is searched in the order of the indices. (Could be used to change the default search order)
|
||||
Example:
|
||||
$smarty->display('[1],[0]foo.bar');
|
||||
|
||||
Filter support
|
||||
==============
|
||||
Optional filter names
|
||||
An optional filter name was added to $smarty->registerFilter(). It can be used to unregister a filter by name.
|
||||
- $smarty->registerFilter('output', $callback, 'name');
|
||||
$smarty->unregister('output', 'name');
|
||||
|
||||
Closures
|
||||
$smarty->registerFilter() does now accept closures.
|
||||
- $smarty->registerFilter('pre', function($source) {return $source;});
|
||||
If no optional filter name was specified it gets the default name 'closure'.
|
||||
If you register multiple closures register each with a unique filter name.
|
||||
- $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_1');
|
||||
- $smarty->registerFilter('pre', function($source) {return $source;}, 'closure_2');
|
||||
|
||||
|
||||
Smarty 3.1.22
|
||||
|
||||
Namespace support within templates
|
||||
==================================
|
||||
Within templates you can now use namespace specifications on:
|
||||
- Constants like foo\bar\FOO
|
||||
- Class names like foo\bar\Baz::FOO, foo\bar\Baz::$foo, foo\bar\Baz::foo()
|
||||
- PHP function names like foo\bar\baz()
|
||||
|
||||
Security
|
||||
========
|
||||
- disable special $smarty variable -
|
||||
The Smarty_Security class has the new property $disabled_special_smarty_vars.
|
||||
It's an array which can be loaded with the $smarty special variable names like
|
||||
'template_object', 'template', 'current_dir' and others which will be disabled.
|
||||
Note: That this security check is performed at compile time.
|
||||
|
||||
- limit template nesting -
|
||||
Property $max_template_nesting of Smarty_Security does set the maximum template nesting level.
|
||||
The main template is level 1. The nesting level is checked at run time. When the maximum will be exceeded
|
||||
an Exception will be thrown. The default setting is 0 which does disable this check.
|
||||
|
||||
- trusted static methods -
|
||||
The Smarty_Security class has the new property $trusted_static_methods to restrict access to static methods.
|
||||
It's an nested array of trusted class and method names.
|
||||
Format:
|
||||
array (
|
||||
'class_1' => array('method_1', 'method_2'), // allowed methods
|
||||
'class_2' => array(), // all methods of class allowed
|
||||
)
|
||||
To disable access for all methods of all classes set $trusted_static_methods = null;
|
||||
The default value is an empty array() which does enables all methods of all classes, but for backward compatibility
|
||||
the setting of $static_classes will be checked.
|
||||
Note: That this security check is performed at compile time.
|
||||
|
||||
- trusted static properties -
|
||||
The Smarty_Security class has the new property $trusted_static_properties to restrict access to static properties.
|
||||
It's an nested array of trusted class and property names.
|
||||
Format:
|
||||
array (
|
||||
'class_1' => array('prop_1', 'prop_2'), // allowed properties listed
|
||||
'class_2' => array(), // all properties of class allowed
|
||||
}
|
||||
To disable access for all properties of all classes set $trusted_static_properties = null;
|
||||
The default value is an empty array() which does enables all properties of all classes, but for backward compatibility
|
||||
the setting of $static_classes will be checked.
|
||||
Note: That this security check is performed at compile time.
|
||||
|
||||
- trusted constants .
|
||||
The Smarty_Security class has the new property $trusted_constants to restrict access to constants.
|
||||
It's an array of trusted constant names.
|
||||
Format:
|
||||
array (
|
||||
'SMARTY_DIR' , // allowed constant
|
||||
}
|
||||
If the array is empty (default) the usage of constants can be controlled with the
|
||||
Smarty_Security::$allow_constants property (default true)
|
||||
|
||||
|
||||
|
||||
Compiled Templates
|
||||
==================
|
||||
Smarty does now automatically detects a change of the $merge_compiled_includes and $escape_html
|
||||
property and creates different compiled templates files depending on the setting.
|
||||
|
||||
Same applies to config files and the $config_overwrite, $config_booleanize and
|
||||
$config_read_hidden properties.
|
||||
|
||||
Debugging
|
||||
=========
|
||||
The layout of the debug window has been changed for better readability
|
||||
|
||||
New class constants
|
||||
Smarty::DEBUG_OFF
|
||||
Smarty::DEBUG_ON
|
||||
Smarty::DEBUG_INDIVIDUAL
|
||||
have been introduced for setting the $debugging property.
|
||||
|
||||
Smarty::DEBUG_INDIVIDUAL will create for each display() and fetch() call an individual debug window.
|
||||
|
575
src/includes/smarty-3.1.48/README
Normal file
|
@ -0,0 +1,575 @@
|
|||
Smarty 3.x
|
||||
|
||||
Author: Monte Ohrt <monte at ohrt dot com >
|
||||
Author: Uwe Tews
|
||||
|
||||
AN INTRODUCTION TO SMARTY 3
|
||||
|
||||
NOTICE FOR 3.1 release:
|
||||
|
||||
Please see the SMARTY_3.1_NOTES.txt file that comes with the distribution.
|
||||
|
||||
NOTICE for 3.0.5 release:
|
||||
|
||||
Smarty now follows the PHP error_reporting level by default. If PHP does not mask E_NOTICE and you try to access an unset template variable, you will now get an E_NOTICE warning. To revert to the old behavior:
|
||||
|
||||
$smarty->error_reporting = E_ALL & ~E_NOTICE;
|
||||
|
||||
NOTICE for 3.0 release:
|
||||
|
||||
IMPORTANT: Some API adjustments have been made between the RC4 and 3.0 release.
|
||||
We felt it is better to make these now instead of after a 3.0 release, then have to
|
||||
immediately deprecate APIs in 3.1. Online documentation has been updated
|
||||
to reflect these changes. Specifically:
|
||||
|
||||
---- API CHANGES RC4 -> 3.0 ----
|
||||
|
||||
$smarty->register->*
|
||||
$smarty->unregister->*
|
||||
$smarty->utility->*
|
||||
$samrty->cache->*
|
||||
|
||||
Have all been changed to local method calls such as:
|
||||
|
||||
$smarty->clearAllCache()
|
||||
$smarty->registerFoo()
|
||||
$smarty->unregisterFoo()
|
||||
$smarty->testInstall()
|
||||
etc.
|
||||
|
||||
Registration of function, block, compiler, and modifier plugins have been
|
||||
consolidated under two API calls:
|
||||
|
||||
$smarty->registerPlugin(...)
|
||||
$smarty->unregisterPlugin(...)
|
||||
|
||||
Registration of pre, post, output and variable filters have been
|
||||
consolidated under two API calls:
|
||||
|
||||
$smarty->registerFilter(...)
|
||||
$smarty->unregisterFilter(...)
|
||||
|
||||
Please refer to the online documentation for all specific changes:
|
||||
|
||||
http://www.smarty.net/documentation
|
||||
|
||||
----
|
||||
|
||||
The Smarty 3 API has been refactored to a syntax geared
|
||||
for consistency and modularity. The Smarty 2 API syntax is still supported, but
|
||||
will throw a deprecation notice. You can disable the notices, but it is highly
|
||||
recommended to adjust your syntax to Smarty 3, as the Smarty 2 syntax must run
|
||||
through an extra rerouting wrapper.
|
||||
|
||||
Basically, all Smarty methods now follow the "fooBarBaz" camel case syntax. Also,
|
||||
all Smarty properties now have getters and setters. So for example, the property
|
||||
$smarty->cache_dir can be set with $smarty->setCacheDir('foo/') and can be
|
||||
retrieved with $smarty->getCacheDir().
|
||||
|
||||
Some of the Smarty 3 APIs have been revoked such as the "is*" methods that were
|
||||
just duplicate functions of the now available "get*" methods.
|
||||
|
||||
Here is a rundown of the Smarty 3 API:
|
||||
|
||||
$smarty->fetch($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
$smarty->display($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
$smarty->isCached($template, $cache_id = null, $compile_id = null)
|
||||
$smarty->createData($parent = null)
|
||||
$smarty->createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
$smarty->enableSecurity()
|
||||
$smarty->disableSecurity()
|
||||
$smarty->setTemplateDir($template_dir)
|
||||
$smarty->addTemplateDir($template_dir)
|
||||
$smarty->templateExists($resource_name)
|
||||
$smarty->loadPlugin($plugin_name, $check = true)
|
||||
$smarty->loadFilter($type, $name)
|
||||
$smarty->setExceptionHandler($handler)
|
||||
$smarty->addPluginsDir($plugins_dir)
|
||||
$smarty->getGlobal($varname = null)
|
||||
$smarty->getRegisteredObject($name)
|
||||
$smarty->getDebugTemplate()
|
||||
$smarty->setDebugTemplate($tpl_name)
|
||||
$smarty->assign($tpl_var, $value = null, $nocache = false)
|
||||
$smarty->assignGlobal($varname, $value = null, $nocache = false)
|
||||
$smarty->assignByRef($tpl_var, &$value, $nocache = false)
|
||||
$smarty->append($tpl_var, $value = null, $merge = false, $nocache = false)
|
||||
$smarty->appendByRef($tpl_var, &$value, $merge = false)
|
||||
$smarty->clearAssign($tpl_var)
|
||||
$smarty->clearAllAssign()
|
||||
$smarty->configLoad($config_file, $sections = null)
|
||||
$smarty->getVariable($variable, $_ptr = null, $search_parents = true, $error_enable = true)
|
||||
$smarty->getConfigVariable($variable)
|
||||
$smarty->getStreamVariable($variable)
|
||||
$smarty->getConfigVars($varname = null)
|
||||
$smarty->clearConfig($varname = null)
|
||||
$smarty->getTemplateVars($varname = null, $_ptr = null, $search_parents = true)
|
||||
$smarty->clearAllCache($exp_time = null, $type = null)
|
||||
$smarty->clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null)
|
||||
|
||||
$smarty->registerPlugin($type, $tag, $callback, $cacheable = true, $cache_attr = array())
|
||||
|
||||
$smarty->registerObject($object_name, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
|
||||
|
||||
$smarty->registerFilter($type, $function_name)
|
||||
$smarty->registerResource($resource_type, $function_names)
|
||||
$smarty->registerDefaultPluginHandler($function_name)
|
||||
$smarty->registerDefaultTemplateHandler($function_name)
|
||||
|
||||
$smarty->unregisterPlugin($type, $tag)
|
||||
$smarty->unregisterObject($object_name)
|
||||
$smarty->unregisterFilter($type, $function_name)
|
||||
$smarty->unregisterResource($resource_type)
|
||||
|
||||
$smarty->compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
|
||||
$smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null)
|
||||
$smarty->testInstall()
|
||||
|
||||
// then all the getters/setters, available for all properties. Here are a few:
|
||||
|
||||
$caching = $smarty->getCaching(); // get $smarty->caching
|
||||
$smarty->setCaching(true); // set $smarty->caching
|
||||
$smarty->setDeprecationNotices(false); // set $smarty->deprecation_notices
|
||||
$smarty->setCacheId($id); // set $smarty->cache_id
|
||||
$debugging = $smarty->getDebugging(); // get $smarty->debugging
|
||||
|
||||
|
||||
FILE STRUCTURE
|
||||
|
||||
The Smarty 3 file structure is similar to Smarty 2:
|
||||
|
||||
/libs/
|
||||
Smarty.class.php
|
||||
/libs/sysplugins/
|
||||
internal.*
|
||||
/libs/plugins/
|
||||
function.mailto.php
|
||||
modifier.escape.php
|
||||
...
|
||||
|
||||
A lot of Smarty 3 core functionality lies in the sysplugins directory; you do
|
||||
not need to change any files here. The /libs/plugins/ folder is where Smarty
|
||||
plugins are located. You can add your own here, or create a separate plugin
|
||||
directory, just the same as Smarty 2. You will still need to create your own
|
||||
/cache/, /templates/, /templates_c/, /configs/ folders. Be sure /cache/ and
|
||||
/templates_c/ are writable.
|
||||
|
||||
The typical way to use Smarty 3 should also look familiar:
|
||||
|
||||
require('Smarty.class.php');
|
||||
$smarty = new Smarty;
|
||||
$smarty->assign('foo','bar');
|
||||
$smarty->display('index.tpl');
|
||||
|
||||
|
||||
However, Smarty 3 works completely different on the inside. Smarty 3 is mostly
|
||||
backward compatible with Smarty 2, except for the following items:
|
||||
|
||||
*) Smarty 3 is PHP 5 only. It will not work with PHP 4.
|
||||
*) The {php} tag is disabled by default. Enable with $smarty->allow_php_tag=true.
|
||||
*) Delimiters surrounded by whitespace are no longer treated as Smarty tags.
|
||||
Therefore, { foo } will not compile as a tag, you must use {foo}. This change
|
||||
Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
|
||||
This can be disabled by setting $smarty->auto_literal = false;
|
||||
*) The Smarty 3 API is a bit different. Many Smarty 2 API calls are deprecated
|
||||
but still work. You will want to update your calls to Smarty 3 for maximum
|
||||
efficiency.
|
||||
|
||||
|
||||
There are many things that are new to Smarty 3. Here are the notable items:
|
||||
|
||||
LEXER/PARSER
|
||||
============
|
||||
|
||||
Smarty 3 now uses a lexing tokenizer for its parser/compiler. Basically, this
|
||||
means Smarty has some syntax additions that make life easier such as in-template
|
||||
math, shorter/intuitive function parameter options, infinite function recursion,
|
||||
more accurate error handling, etc.
|
||||
|
||||
|
||||
WHAT IS NEW IN SMARTY TEMPLATE SYNTAX
|
||||
=====================================
|
||||
|
||||
Smarty 3 allows expressions almost anywhere. Expressions can include PHP
|
||||
functions as long as they are not disabled by the security policy, object
|
||||
methods and properties, etc. The {math} plugin is no longer necessary but
|
||||
is still supported for BC.
|
||||
|
||||
Examples:
|
||||
{$x+$y} will output the sum of x and y.
|
||||
{$foo = strlen($bar)} function in assignment
|
||||
{assign var=foo value= $x+$y} in attributes
|
||||
{$foo = myfunct( ($x+$y)*3 )} as function parameter
|
||||
{$foo[$x+3]} as array index
|
||||
|
||||
Smarty tags can be used as values within other tags.
|
||||
Example: {$foo={counter}+3}
|
||||
|
||||
Smarty tags can also be used inside double quoted strings.
|
||||
Example: {$foo="this is message {counter}"}
|
||||
|
||||
You can define arrays within templates.
|
||||
Examples:
|
||||
{assign var=foo value=[1,2,3]}
|
||||
{assign var=foo value=['y'=>'yellow','b'=>'blue']}
|
||||
Arrays can be nested.
|
||||
{assign var=foo value=[1,[9,8],3]}
|
||||
|
||||
There is a new short syntax supported for assigning variables.
|
||||
Example: {$foo=$bar+2}
|
||||
|
||||
You can assign a value to a specific array element. If the variable exists but
|
||||
is not an array, it is converted to an array before the new values are assigned.
|
||||
Examples:
|
||||
{$foo['bar']=1}
|
||||
{$foo['bar']['blar']=1}
|
||||
|
||||
You can append values to an array. If the variable exists but is not an array,
|
||||
it is converted to an array before the new values are assigned.
|
||||
Example: {$foo[]=1}
|
||||
|
||||
You can use a PHP-like syntax for accessing array elements, as well as the
|
||||
original "dot" notation.
|
||||
Examples:
|
||||
{$foo[1]} normal access
|
||||
{$foo['bar']}
|
||||
{$foo['bar'][1]}
|
||||
{$foo[$x+$x]} index may contain any expression
|
||||
{$foo[$bar[1]]} nested index
|
||||
{$foo[section_name]} smarty section access, not array access!
|
||||
|
||||
The original "dot" notation stays, and with improvements.
|
||||
Examples:
|
||||
{$foo.a.b.c} => $foo['a']['b']['c']
|
||||
{$foo.a.$b.c} => $foo['a'][$b]['c'] with variable index
|
||||
{$foo.a.{$b+4}.c} => $foo['a'][$b+4]['c'] with expression as index
|
||||
{$foo.a.{$b.c}} => $foo['a'][$b['c']] with nested index
|
||||
|
||||
note that { and } are used to address ambiguties when nesting the dot syntax.
|
||||
|
||||
Variable names themselves can be variable and contain expressions.
|
||||
Examples:
|
||||
$foo normal variable
|
||||
$foo_{$bar} variable name containing other variable
|
||||
$foo_{$x+$y} variable name containing expressions
|
||||
$foo_{$bar}_buh_{$blar} variable name with multiple segments
|
||||
{$foo_{$x}} will output the variable $foo_1 if $x has a value of 1.
|
||||
|
||||
Object method chaining is implemented.
|
||||
Example: {$object->method1($x)->method2($y)}
|
||||
|
||||
{for} tag added for looping (replacement for {section} tag):
|
||||
{for $x=0, $y=count($foo); $x<$y; $x++} .... {/for}
|
||||
Any number of statements can be used separated by comma as the first
|
||||
initial expression at {for}.
|
||||
|
||||
{for $x = $start to $end step $step} ... {/for}is in the SVN now .
|
||||
You can use also
|
||||
{for $x = $start to $end} ... {/for}
|
||||
In this case the step value will be automatically 1 or -1 depending on the start and end values.
|
||||
Instead of $start and $end you can use any valid expression.
|
||||
Inside the loop the following special vars can be accessed:
|
||||
$x@iteration = number of iteration
|
||||
$x@total = total number of iterations
|
||||
$x@first = true on first iteration
|
||||
$x@last = true on last iteration
|
||||
|
||||
|
||||
The Smarty 2 {section} syntax is still supported.
|
||||
|
||||
New shorter {foreach} syntax to loop over an array.
|
||||
Example: {foreach $myarray as $var}...{/foreach}
|
||||
|
||||
Within the foreach loop, properties are access via:
|
||||
|
||||
$var@key foreach $var array key
|
||||
$var@iteration foreach current iteration count (1,2,3...)
|
||||
$var@index foreach current index count (0,1,2...)
|
||||
$var@total foreach $var array total
|
||||
$var@first true on first iteration
|
||||
$var@last true on last iteration
|
||||
|
||||
The Smarty 2 {foreach} tag syntax is still supported.
|
||||
|
||||
NOTE: {$bar[foo]} still indicates a variable inside of a {section} named foo.
|
||||
If you want to access an array element with index foo, you must use quotes
|
||||
such as {$bar['foo']}, or use the dot syntax {$bar.foo}.
|
||||
|
||||
while block tag is now implemented:
|
||||
{while $foo}...{/while}
|
||||
{while $x lt 10}...{/while}
|
||||
|
||||
Direct access to PHP functions:
|
||||
Just as you can use PHP functions as modifiers directly, you can now access
|
||||
PHP functions directly, provided they are permitted by security settings:
|
||||
{time()}
|
||||
|
||||
There is a new {function}...{/function} block tag to implement a template function.
|
||||
This enables reuse of code sequences like a plugin function. It can call itself recursively.
|
||||
Template function must be called with the new {call name=foo...} tag.
|
||||
|
||||
Example:
|
||||
|
||||
Template file:
|
||||
{function name=menu level=0}
|
||||
<ul class="level{$level}">
|
||||
{foreach $data as $entry}
|
||||
{if is_array($entry)}
|
||||
<li>{$entry@key}</li>
|
||||
{call name=menu data=$entry level=$level+1}
|
||||
{else}
|
||||
<li>{$entry}</li>
|
||||
{/if}
|
||||
{/foreach}
|
||||
</ul>
|
||||
{/function}
|
||||
|
||||
{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
|
||||
['item3-3-1','item3-3-2']],'item4']}
|
||||
|
||||
{call name=menu data=$menu}
|
||||
|
||||
|
||||
Generated output:
|
||||
* item1
|
||||
* item2
|
||||
* item3
|
||||
o item3-1
|
||||
o item3-2
|
||||
o item3-3
|
||||
+ item3-3-1
|
||||
+ item3-3-2
|
||||
* item4
|
||||
|
||||
The function tag itself must have the "name" attribute. This name is the tag
|
||||
name when calling the function. The function tag may have any number of
|
||||
additional attributes. These will be default settings for local variables.
|
||||
|
||||
New {nocache} block function:
|
||||
{nocache}...{/nocache} will declare a section of the template to be non-cached
|
||||
when template caching is enabled.
|
||||
|
||||
New nocache attribute:
|
||||
You can declare variable/function output as non-cached with the nocache attribute.
|
||||
Examples:
|
||||
|
||||
{$foo nocache=true}
|
||||
{$foo nocache} /* same */
|
||||
|
||||
{foo bar="baz" nocache=true}
|
||||
{foo bar="baz" nocache} /* same */
|
||||
|
||||
{time() nocache=true}
|
||||
{time() nocache} /* same */
|
||||
|
||||
Or you can also assign the variable in your script as nocache:
|
||||
$smarty->assign('foo',$something,true); // third param is nocache setting
|
||||
{$foo} /* non-cached */
|
||||
|
||||
$smarty.current_dir returns the directory name of the current template.
|
||||
|
||||
You can use strings directly as templates with the "string" resource type.
|
||||
Examples:
|
||||
$smarty->display('string:This is my template, {$foo}!'); // php
|
||||
{include file="string:This is my template, {$foo}!"} // template
|
||||
|
||||
|
||||
|
||||
VARIABLE SCOPE / VARIABLE STORAGE
|
||||
=================================
|
||||
|
||||
In Smarty 2, all assigned variables were stored within the Smarty object.
|
||||
Therefore, all variables assigned in PHP were accessible by all subsequent
|
||||
fetch and display template calls.
|
||||
|
||||
In Smarty 3, we have the choice to assign variables to the main Smarty object,
|
||||
to user-created data objects, and to user-created template objects.
|
||||
These objects can be chained. The object at the end of a chain can access all
|
||||
variables belonging to that template and all variables within the parent objects.
|
||||
The Smarty object can only be the root of a chain, but a chain can be isolated
|
||||
from the Smarty object.
|
||||
|
||||
All known Smarty assignment interfaces will work on the data and template objects.
|
||||
|
||||
Besides the above mentioned objects, there is also a special storage area for
|
||||
global variables.
|
||||
|
||||
A Smarty data object can be created as follows:
|
||||
$data = $smarty->createData(); // create root data object
|
||||
$data->assign('foo','bar'); // assign variables as usual
|
||||
$data->config_load('my.conf'); // load config file
|
||||
|
||||
$data= $smarty->createData($smarty); // create data object having a parent link to
|
||||
the Smarty object
|
||||
|
||||
$data2= $smarty->createData($data); // create data object having a parent link to
|
||||
the $data data object
|
||||
|
||||
A template object can be created by using the createTemplate method. It has the
|
||||
same parameter assignments as the fetch() or display() method.
|
||||
Function definition:
|
||||
function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null)
|
||||
|
||||
The first parameter can be a template name, a smarty object or a data object.
|
||||
|
||||
Examples:
|
||||
$tpl = $smarty->createTemplate('mytpl.tpl'); // create template object not linked to any parent
|
||||
$tpl->assign('foo','bar'); // directly assign variables
|
||||
$tpl->config_load('my.conf'); // load config file
|
||||
|
||||
$tpl = $smarty->createTemplate('mytpl.tpl',$smarty); // create template having a parent link to the Smarty object
|
||||
$tpl = $smarty->createTemplate('mytpl.tpl',$data); // create template having a parent link to the $data object
|
||||
|
||||
The standard fetch() and display() methods will implicitly create a template object.
|
||||
If the $parent parameter is not specified in these method calls, the template object
|
||||
is will link back to the Smarty object as it's parent.
|
||||
|
||||
If a template is called by an {include...} tag from another template, the
|
||||
subtemplate links back to the calling template as it's parent.
|
||||
|
||||
All variables assigned locally or from a parent template are accessible. If the
|
||||
template creates or modifies a variable by using the {assign var=foo...} or
|
||||
{$foo=...} tags, these new values are only known locally (local scope). When the
|
||||
template exits, none of the new variables or modifications can be seen in the
|
||||
parent template(s). This is same behavior as in Smarty 2.
|
||||
|
||||
With Smarty 3, we can assign variables with a scope attribute which allows the
|
||||
availablility of these new variables or modifications globally (ie in the parent
|
||||
templates.)
|
||||
|
||||
Possible scopes are local, parent, root and global.
|
||||
Examples:
|
||||
{assign var=foo value='bar'} // no scope is specified, the default 'local'
|
||||
{$foo='bar'} // same, local scope
|
||||
{assign var=foo value='bar' scope='local'} // same, local scope
|
||||
|
||||
{assign var=foo value='bar' scope='parent'} // Values will be available to the parent object
|
||||
{$foo='bar' scope='parent'} // (normally the calling template)
|
||||
|
||||
{assign var=foo value='bar' scope='root'} // Values will be exported up to the root object, so they can
|
||||
{$foo='bar' scope='root'} // be seen from all templates using the same root.
|
||||
|
||||
{assign var=foo value='bar' scope='global'} // Values will be exported to global variable storage,
|
||||
{$foo='bar' scope='global'} // they are available to any and all templates.
|
||||
|
||||
|
||||
The scope attribute can also be attached to the {include...} tag. In this case,
|
||||
the specified scope will be the default scope for all assignments within the
|
||||
included template.
|
||||
|
||||
|
||||
PLUGINS
|
||||
=======
|
||||
|
||||
Smarty 3 plugins follow the same coding rules as in Smarty 2.
|
||||
The main difference is that the template object is now passed in place of the smarty object.
|
||||
The smarty object can be still be accessed through $template->smarty.
|
||||
|
||||
smarty_plugintype_name (array $params, Smarty_Internal_Template $template)
|
||||
|
||||
The Smarty 2 plugins are still compatible as long as they do not make use of specific Smarty 2 internals.
|
||||
|
||||
|
||||
TEMPLATE INHERITANCE:
|
||||
=====================
|
||||
|
||||
With template inheritance you can define blocks, which are areas that can be
|
||||
overridden by child templates, so your templates could look like this:
|
||||
|
||||
parent.tpl:
|
||||
<html>
|
||||
<head>
|
||||
<title>{block name='title'}My site name{/block}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{block name='page-title'}Default page title{/block}</h1>
|
||||
<div id="content">
|
||||
{block name='content'}
|
||||
Default content
|
||||
{/block}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
child.tpl:
|
||||
{extends file='parent.tpl'}
|
||||
{block name='title'}
|
||||
Child title
|
||||
{/block}
|
||||
|
||||
grandchild.tpl:
|
||||
{extends file='child.tpl'}
|
||||
{block name='title'}Home - {$smarty.block.parent}{/block}
|
||||
{block name='page-title'}My home{/block}
|
||||
{block name='content'}
|
||||
{foreach $images as $img}
|
||||
<img src="{$img.url}" alt="{$img.description}" />
|
||||
{/foreach}
|
||||
{/block}
|
||||
|
||||
We redefined all the blocks here, however in the title block we used {$smarty.block.parent},
|
||||
which tells Smarty to insert the default content from the parent template in its place.
|
||||
The content block was overridden to display the image files, and page-title has also be
|
||||
overridden to display a completely different title.
|
||||
|
||||
If we render grandchild.tpl we will get this:
|
||||
<html>
|
||||
<head>
|
||||
<title>Home - Child title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>My home</h1>
|
||||
<div id="content">
|
||||
<img src="/example.jpg" alt="image" />
|
||||
<img src="/example2.jpg" alt="image" />
|
||||
<img src="/example3.jpg" alt="image" />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
NOTE: In the child templates everything outside the {extends} or {block} tag sections
|
||||
is ignored.
|
||||
|
||||
The inheritance tree can be as big as you want (meaning you can extend a file that
|
||||
extends another one that extends another one and so on..), but be aware that all files
|
||||
have to be checked for modifications at runtime so the more inheritance the more overhead you add.
|
||||
|
||||
Instead of defining the parent/child relationships with the {extends} tag in the child template you
|
||||
can use the resource as follow:
|
||||
|
||||
$smarty->display('extends:parent.tpl|child.tpl|grandchild.tpl');
|
||||
|
||||
Child {block} tags may optionally have a append or prepend attribute. In this case the parent block content
|
||||
is appended or prepended to the child block content.
|
||||
|
||||
{block name='title' append} My title {/block}
|
||||
|
||||
|
||||
PHP STREAMS:
|
||||
============
|
||||
|
||||
(see online documentation)
|
||||
|
||||
VARIBLE FILTERS:
|
||||
================
|
||||
|
||||
(see online documentation)
|
||||
|
||||
|
||||
STATIC CLASS ACCESS AND NAMESPACE SUPPORT
|
||||
=========================================
|
||||
|
||||
You can register a class with optional namespace for the use in the template like:
|
||||
|
||||
$smarty->register->templateClass('foo','name\name2\myclass');
|
||||
|
||||
In the template you can use it like this:
|
||||
{foo::method()} etc.
|
||||
|
||||
|
||||
=======================
|
||||
|
||||
Please look through it and send any questions/suggestions/etc to the forums.
|
||||
|
||||
http://www.phpinsider.com/smarty-forum/viewtopic.php?t=14168
|
||||
|
||||
Monte and Uwe
|
78
src/includes/smarty-3.1.48/README.md
Normal file
|
@ -0,0 +1,78 @@
|
|||
# Smarty 3 template engine
|
||||
[smarty.net](https://www.smarty.net/)
|
||||
|
||||
[](https://travis-ci.org/smarty-php/smarty)
|
||||
|
||||
## Documentation
|
||||
|
||||
For documentation see
|
||||
[www.smarty.net/docs/en/](https://www.smarty.net/docs/en/)
|
||||
|
||||
## Requirements
|
||||
|
||||
Smarty can be run with PHP 5.2 to PHP 7.4.
|
||||
|
||||
## Distribution repository
|
||||
|
||||
> Smarty 3.1.28 introduces run time template inheritance
|
||||
|
||||
> Read the NEW_FEATURES and INHERITANCE_RELEASE_NOTES file for recent extensions to Smarty 3.1 functionality
|
||||
|
||||
Smarty versions 3.1.11 or later are now on GitHub and can be installed with Composer.
|
||||
|
||||
|
||||
The "smarty/smarty" package will start at libs/.... subfolder.
|
||||
|
||||
To get the latest stable version of Smarty 3.1 use:
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1"
|
||||
}
|
||||
```
|
||||
|
||||
in your composer.json file.
|
||||
|
||||
To get the trunk version use:
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty": "~3.1@dev"
|
||||
}
|
||||
```
|
||||
|
||||
For a specific version use something like:
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty": "3.1.19"
|
||||
}
|
||||
```
|
||||
|
||||
PHPUnit test can be installed by corresponding composer entries like:
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty-phpunit": "3.1.19"
|
||||
}
|
||||
```
|
||||
|
||||
Similar applies for the lexer/parser generator.
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty-lexer": "3.1.19"
|
||||
}
|
||||
```
|
||||
|
||||
Or you could use:
|
||||
|
||||
```json
|
||||
"require": {
|
||||
"smarty/smarty-dev": "3.1.19"
|
||||
}
|
||||
```
|
||||
|
||||
Which is a wrapper to install all 3 packages.
|
||||
|
||||
Composer can also be used for Smarty2 versions 2.6.24 to 2.6.30.
|
19
src/includes/smarty-3.1.48/SECURITY.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
Smarty currently supports the latest minor version of Smarty 3 and Smarty 4. (Smarty 4 has not been released yet.)
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 4.0.x | :white_check_mark: |
|
||||
| 3.1.x | :white_check_mark: |
|
||||
| < 3.1 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you have discovered a security issue with Smarty, please contact us at mail [at] simonwisselink.nl. Do not
|
||||
disclose your findings publicly and PLEASE PLEASE do not file an Issue.
|
||||
|
||||
We will try to confirm the vulnerability and develop a fix if appropriate. When we release the fix, we will publish
|
||||
a security release. Please let us know if you want to be credited.
|
109
src/includes/smarty-3.1.48/SMARTY_2_BC_NOTES.txt
Normal file
|
@ -0,0 +1,109 @@
|
|||
= Known incompatibilities with Smarty 2 =
|
||||
|
||||
== Syntax ==
|
||||
|
||||
Smarty 3 API has a new syntax. Much of the Smarty 2 syntax is supported
|
||||
by a wrapper but deprecated. See the README that comes with Smarty 3 for more
|
||||
information.
|
||||
|
||||
The {$array|@mod} syntax has always been a bit confusing, where an "@" is required
|
||||
to apply a modifier to an array instead of the individual elements. Normally you
|
||||
always want the modifier to apply to the variable regardless of its type. In Smarty 3,
|
||||
{$array|mod} and {$array|@mod} behave identical. It is safe to drop the "@" and the
|
||||
modifier will still apply to the array. If you really want the modifier to apply to
|
||||
each array element, you must loop the array in-template, or use a custom modifier that
|
||||
supports array iteration. Most smarty functions already escape values where necessary
|
||||
such as {html_options}
|
||||
|
||||
== PHP Version ==
|
||||
Smarty 3 is PHP 5 only. It will not work with PHP 4.
|
||||
|
||||
== {php} Tag ==
|
||||
The {php} tag is disabled by default. The use of {php} tags is
|
||||
deprecated. It can be enabled with $smarty->allow_php_tag=true.
|
||||
|
||||
But if you scatter PHP code which belongs together into several
|
||||
{php} tags it may not work any longer.
|
||||
|
||||
== Delimiters and whitespace ==
|
||||
Delimiters surrounded by whitespace are no longer treated as Smarty tags.
|
||||
Therefore, { foo } will not compile as a tag, you must use {foo}. This change
|
||||
Makes Javascript/CSS easier to work with, eliminating the need for {literal}.
|
||||
This can be disabled by setting $smarty->auto_literal = false;
|
||||
|
||||
== Unquoted Strings ==
|
||||
Smarty 2 was a bit more forgiving (and ambiguous) when it comes to unquoted strings
|
||||
in parameters. Smarty3 is more restrictive. You can still pass strings without quotes
|
||||
so long as they contain no special characters. (anything outside of A-Za-z0-9_)
|
||||
|
||||
For example filename strings must be quoted
|
||||
<source lang="smarty">
|
||||
{include file='path/foo.tpl'}
|
||||
</source>
|
||||
|
||||
== Extending the Smarty class ==
|
||||
Smarty 3 makes use of the __construct method for initialization. If you are extending
|
||||
the Smarty class, its constructor is not called implicitly if the your child class defines
|
||||
its own constructor. In order to run Smarty's constructor, a call to parent::__construct()
|
||||
within your child constructor is required.
|
||||
|
||||
<source lang="php">
|
||||
class MySmarty extends Smarty {
|
||||
function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
// your initialization code goes here
|
||||
|
||||
}
|
||||
}
|
||||
</source>
|
||||
|
||||
== Autoloader ==
|
||||
Smarty 3 does register its own autoloader with spl_autoload_register. If your code has
|
||||
an existing __autoload function then this function must be explicitly registered on
|
||||
the __autoload stack. See http://us3.php.net/manual/en/function.spl-autoload-register.php
|
||||
for further details.
|
||||
|
||||
== Plugin Filenames ==
|
||||
Smarty 3 optionally supports the PHP spl_autoloader. The autoloader requires filenames
|
||||
to be lower case. Because of this, Smarty plugin file names must also be lowercase.
|
||||
In Smarty 2, mixed case file names did work.
|
||||
|
||||
== Scope of Special Smarty Variables ==
|
||||
In Smarty 2 the special Smarty variables $smarty.section... and $smarty.foreach...
|
||||
had global scope. If you had loops with the same name in subtemplates you could accidentally
|
||||
overwrite values of parent template.
|
||||
|
||||
In Smarty 3 these special Smarty variable have only local scope in the template which
|
||||
is defining the loop. If you need their value in a subtemplate you have to pass them
|
||||
as parameter.
|
||||
<source lang="smarty">
|
||||
{include file='path/foo.tpl' index=$smarty.section.foo.index}
|
||||
</source>
|
||||
|
||||
== SMARTY_RESOURCE_CHAR_SET ==
|
||||
Smarty 3 sets the constant SMARTY_RESOURCE_CHAR_SET to utf-8 as default template charset.
|
||||
This is now used also on modifiers like escape as default charset. If your templates use
|
||||
other charsets make sure that you define the constant accordingly. Otherwise you may not
|
||||
get any output.
|
||||
|
||||
== newline at {if} tags ==
|
||||
A \n was added to the compiled code of the {if},{else},{elseif},{/if} tags to get output of newlines as expected by the template source.
|
||||
If one of the {if} tags is at the line end you will now get a newline in the HTML output.
|
||||
|
||||
== trigger_error() ==
|
||||
The API function trigger_error() has been removed because it did just map to PHP trigger_error.
|
||||
However it's still included in the Smarty2 API wrapper.
|
||||
|
||||
== Smarty constants ==
|
||||
The constants
|
||||
SMARTY_PHP_PASSTHRU
|
||||
SMARTY_PHP_QUOTE
|
||||
SMARTY_PHP_REMOVE
|
||||
SMARTY_PHP_ALLOW
|
||||
have been replaced with class constants
|
||||
Smarty::PHP_PASSTHRU
|
||||
Smarty::PHP_QUOTE
|
||||
Smarty::PHP_REMOVE
|
||||
Smarty::PHP_ALLOW
|
||||
|
24
src/includes/smarty-3.1.48/SMARTY_3.0_BC_NOTES.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
== Smarty2 backward compatibility ==
|
||||
All Smarty2 specific API functions and deprecated functionality has been moved
|
||||
to the SmartyBC class.
|
||||
|
||||
== {php} Tag ==
|
||||
The {php} tag is no longer available in the standard Smarty calls.
|
||||
The use of {php} tags is deprecated and only available in the SmartyBC class.
|
||||
|
||||
== {include_php} Tag ==
|
||||
The {include_php} tag is no longer available in the standard Smarty calls.
|
||||
The use of {include_php} tags is deprecated and only available in the SmartyBC class.
|
||||
|
||||
== php template resource ==
|
||||
The support of the php template resource is removed.
|
||||
|
||||
== $cache_dir, $compile_dir, $config_dir, $template_dir access ==
|
||||
The mentioned properties can't be accessed directly any longer. You must use
|
||||
corresponding getter/setters like addConfigDir(), setConfigDir(), getConfigDir()
|
||||
|
||||
== obsolete Smarty class properties ==
|
||||
The following no longer used properties are removed:
|
||||
$allow_php_tag
|
||||
$allow_php_template
|
||||
$deprecation_notices
|
306
src/includes/smarty-3.1.48/SMARTY_3.1_NOTES.txt
Normal file
|
@ -0,0 +1,306 @@
|
|||
Smarty 3.1 Notes
|
||||
================
|
||||
|
||||
Smarty 3.1 is a departure from 2.0 compatibility. Most notably, all
|
||||
backward compatibility has been moved to a separate class file named
|
||||
SmartyBC.class.php. If you require compatibility with 2.0, you will
|
||||
need to use this class.
|
||||
|
||||
Some differences from 3.0 are also present. 3.1 begins the journey of
|
||||
requiring setters/getters for property access. So far this is only
|
||||
implemented on the five directory properties: template_dir,
|
||||
plugins_dir, configs_dir, compile_dir and cache_dir. These properties
|
||||
are now protected, it is required to use the setters/getters instead.
|
||||
That said, direct property access will still work, however slightly
|
||||
slower since they will now fall through __set() and __get() and in
|
||||
turn passed through the setter/getter methods. 3.2 will exhibit a full
|
||||
list of setter/getter methods for all (currently) public properties,
|
||||
so code-completion in your IDE will work as expected.
|
||||
|
||||
There is absolutely no PHP allowed in templates any more. All
|
||||
deprecated features of Smarty 2.0 are gone. Again, use the SmartyBC
|
||||
class if you need any backward compatibility.
|
||||
|
||||
Internal Changes
|
||||
|
||||
Full UTF-8 Compatibility
|
||||
|
||||
The plugins shipped with Smarty 3.1 have been rewritten to fully
|
||||
support UTF-8 strings if Multibyte String is available. Without
|
||||
MBString UTF-8 cannot be handled properly. For those rare cases where
|
||||
templates themselves have to juggle encodings, the new modifiers
|
||||
to_charset and from_charset may come in handy.
|
||||
|
||||
Plugin API and Performance
|
||||
|
||||
All Plugins (modifiers, functions, blocks, resources,
|
||||
default_template_handlers, etc) are now receiving the
|
||||
Smarty_Internal_Template instance, where they were supplied with the
|
||||
Smarty instance in Smarty 3.0. *. As The Smarty_Internal_Template
|
||||
mimics the behavior of Smarty, this API simplification should not
|
||||
require any changes to custom plugins.
|
||||
|
||||
The plugins shipped with Smarty 3.1 have been rewritten for better
|
||||
performance. Most notably {html_select_date} and {html_select_time}
|
||||
have been improved vastly. Performance aside, plugins have also been
|
||||
reviewed and generalized in their API. {html_select_date} and
|
||||
{html_select_time} now share almost all available options.
|
||||
|
||||
The escape modifier now knows the $double_encode option, which will
|
||||
prevent entities from being encoded again.
|
||||
|
||||
The capitalize modifier now know the $lc_rest option, which makes sure
|
||||
all letters following a capital letter are lower-cased.
|
||||
|
||||
The count_sentences modifier now accepts (.?!) as
|
||||
legitimate endings of a sentence - previously only (.) was
|
||||
accepted
|
||||
|
||||
The new unescape modifier is there to reverse the effects of the
|
||||
escape modifier. This applies to the escape formats html, htmlall and
|
||||
entity.
|
||||
|
||||
default_template_handler_func
|
||||
|
||||
The invocation of $smarty->$default_template_handler_func had to be
|
||||
altered. Instead of a Smarty_Internal_Template, the fifth argument is
|
||||
now provided with the Smarty instance. New footprint:
|
||||
|
||||
|
||||
/**
|
||||
* Default Template Handler
|
||||
*
|
||||
* called when Smarty's file: resource is unable to load a requested file
|
||||
*
|
||||
* @param string $type resource type (e.g. "file", "string", "eval", "resource")
|
||||
* @param string $name resource name (e.g. "foo/bar.tpl")
|
||||
* @param string &$content template's content
|
||||
* @param integer &$modified template's modification time
|
||||
* @param Smarty $smarty Smarty instance
|
||||
* @return string|boolean path to file or boolean true if $content and $modified
|
||||
* have been filled, boolean false if no default template
|
||||
* could be loaded
|
||||
*/
|
||||
function default_template_handler_func($type, $name, &$content, &$modified, Smarty $smarty) {
|
||||
if (false) {
|
||||
// return corrected filepath
|
||||
return "/tmp/some/foobar.tpl";
|
||||
} elseif (false) {
|
||||
// return a template directly
|
||||
$content = "the template source";
|
||||
$modified = time();
|
||||
return true;
|
||||
} else {
|
||||
// tell smarty that we failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Stuff done to the compiler
|
||||
|
||||
Many performance improvements have happened internally. One notable
|
||||
improvement is that all compiled templates are now handled as PHP
|
||||
functions. This speeds up repeated templates tremendously, as each one
|
||||
calls an (in-memory) PHP function instead of performing another file
|
||||
include/scan.
|
||||
|
||||
New Features
|
||||
|
||||
Template syntax
|
||||
|
||||
{block}..{/block}
|
||||
|
||||
The {block} tag has a new hide option flag. It does suppress the block
|
||||
content if no corresponding child block exists.
|
||||
EXAMPLE:
|
||||
parent.tpl
|
||||
{block name=body hide} child content "{$smarty.block.child}" was
|
||||
inserted {block}
|
||||
In the above example the whole block will be suppressed if no child
|
||||
block "body" is existing.
|
||||
|
||||
{setfilter}..{/setfilter}
|
||||
|
||||
The new {setfilter} block tag allows the definition of filters which
|
||||
run on variable output.
|
||||
SYNTAX:
|
||||
{setfilter filter1|filter2|filter3....}
|
||||
Smarty3 will lookup up matching filters in the following search order:
|
||||
1. variable filter plugin in plugins_dir.
|
||||
2. a valid modifier. A modifier specification will also accept
|
||||
additional parameter like filter2:'foo'
|
||||
3. a PHP function
|
||||
{/setfilter} will turn previous filter setting off again.
|
||||
{setfilter} tags can be nested.
|
||||
EXAMPLE:
|
||||
{setfilter filter1}
|
||||
{$foo}
|
||||
{setfilter filter2}
|
||||
{$bar}
|
||||
{/setfilter}
|
||||
{$buh}
|
||||
{/setfilter}
|
||||
{$blar}
|
||||
In the above example filter1 will run on the output of $foo, filter2
|
||||
on $bar, filter1 again on $buh and no filter on $blar.
|
||||
NOTES:
|
||||
- {$foo nofilter} will suppress the filters
|
||||
- These filters will run in addition to filters defined by
|
||||
registerFilter('variable',...), autoLoadFilter('variable',...) and
|
||||
defined default modifier.
|
||||
- {setfilter} will effect only the current template, not included
|
||||
subtemplates.
|
||||
|
||||
Resource API
|
||||
|
||||
Smarty 3.1 features a new approach to resource management. The
|
||||
Smarty_Resource API allows simple, yet powerful integration of custom
|
||||
resources for templates and configuration files. It offers simple
|
||||
functions for loading data from a custom resource (e.g. database) as
|
||||
well as define new template types adhering to the special
|
||||
non-compiling (e,g, plain php) and non-compile-caching (e.g. eval:
|
||||
resource type) resources.
|
||||
|
||||
See demo/plugins/resource.mysql.php for an example custom database
|
||||
resource.
|
||||
|
||||
Note that old-fashioned registration of callbacks for resource
|
||||
management has been deprecated but is still possible with SmartyBC.
|
||||
|
||||
CacheResource API
|
||||
|
||||
In line with the Resource API, the CacheResource API offers a more
|
||||
comfortable handling of output-cache data. With the
|
||||
Smarty_CacheResource_Custom accessing databases is made simple. With
|
||||
the introduction of Smarty_CacheResource_KeyValueStore the
|
||||
implementation of resources like memcache or APC became a no-brainer;
|
||||
simple hash-based storage systems are now supporting hierarchical
|
||||
output-caches.
|
||||
|
||||
See demo/plugins/cacheresource.mysql.php for an example custom
|
||||
database CacheResource.
|
||||
See demo/plugins/cacheresource.memcache.php for an example custom
|
||||
memcache CacheResource using the KeyValueStore helper.
|
||||
|
||||
Note that old-fashioned registration of $cache_handler is not possible
|
||||
anymore. As the functionality had not been ported to Smarty 3.0.x
|
||||
properly, it has been dropped from 3.1 completely.
|
||||
|
||||
Locking facilities have been implemented to avoid concurrent cache
|
||||
generation. Enable cache locking by setting
|
||||
$smarty->cache_locking = true;
|
||||
|
||||
Relative Paths in Templates (File-Resource)
|
||||
|
||||
As of Smarty 3.1 {include file="../foo.tpl"} and {include
|
||||
file="./foo.tpl"} will resolve relative to the template they're in.
|
||||
Relative paths are available with {include file="..."} and
|
||||
{extends file="..."}. As $smarty->fetch('../foo.tpl') and
|
||||
$smarty->fetch('./foo.tpl') cannot be relative to a template, an
|
||||
exception is thrown.
|
||||
|
||||
Addressing a specific $template_dir
|
||||
|
||||
Smarty 3.1 introduces the $template_dir index notation.
|
||||
$smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"}
|
||||
require the template bar.tpl to be loaded from $template_dir['foo'];
|
||||
Smarty::setTemplateDir() and Smarty::addTemplateDir() offer ways to
|
||||
define indexes along with the actual directories.
|
||||
|
||||
Mixing Resources in extends-Resource
|
||||
|
||||
Taking the php extends: template resource one step further, it is now
|
||||
possible to mix resources within an extends: call like
|
||||
$smarty->fetch("extends:file:foo.tpl|db:bar.tpl");
|
||||
|
||||
To make eval: and string: resources available to the inheritance
|
||||
chain, eval:base64:TPL_STRING and eval:urlencode:TPL_STRING have been
|
||||
introduced. Supplying the base64 or urlencode flags will trigger
|
||||
decoding the TPL_STRING in with either base64_decode() or urldecode().
|
||||
|
||||
extends-Resource in template inheritance
|
||||
|
||||
Template based inheritance may now inherit from php's extends:
|
||||
resource like {extends file="extends:foo.tpl|db:bar.tpl"}.
|
||||
|
||||
New Smarty property escape_html
|
||||
|
||||
$smarty->escape_html = true will autoescape all template variable
|
||||
output by calling htmlspecialchars({$output}, ENT_QUOTES,
|
||||
SMARTY_RESOURCE_CHAR_SET).
|
||||
NOTE:
|
||||
This is a compile time option. If you change the setting you must make
|
||||
sure that the templates get recompiled.
|
||||
|
||||
New option at Smarty property compile_check
|
||||
|
||||
The automatic recompilation of modified templates can now be
|
||||
controlled by the following settings:
|
||||
$smarty->compile_check = COMPILECHECK_OFF (false) - template files
|
||||
will not be checked
|
||||
$smarty->compile_check = COMPILECHECK_ON (true) - template files will
|
||||
always be checked
|
||||
$smarty->compile_check = COMPILECHECK_CACHEMISS - template files will
|
||||
be checked if caching is enabled and there is no existing cache file
|
||||
or it has expired
|
||||
|
||||
Automatic recompilation on Smarty version change
|
||||
|
||||
Templates will now be automatically recompiled on Smarty version
|
||||
changes to avoide incompatibillities in the compiled code. Compiled
|
||||
template checked against the current setting of the SMARTY_VERSION
|
||||
constant.
|
||||
|
||||
default_config_handler_func()
|
||||
|
||||
Analogous to the default_template_handler_func()
|
||||
default_config_handler_func() has been introduced.
|
||||
|
||||
default_plugin_handler_func()
|
||||
|
||||
An optional default_plugin_handler_func() can be defined which gets called
|
||||
by the compiler on tags which can't be resolved internally or by plugins.
|
||||
The default_plugin_handler() can map tags to plugins on the fly.
|
||||
|
||||
New getters/setters
|
||||
|
||||
The following setters/getters will be part of the official
|
||||
documentation, and will be strongly recommended. Direct property
|
||||
access will still work for the foreseeable future... it will be
|
||||
transparently routed through the setters/getters, and consequently a
|
||||
bit slower.
|
||||
|
||||
array|string getTemplateDir( [string $index] )
|
||||
replaces $smarty->template_dir; and $smarty->template_dir[$index];
|
||||
Smarty setTemplateDir( array|string $path )
|
||||
replaces $smarty->template_dir = "foo"; and $smarty->template_dir =
|
||||
array("foo", "bar");
|
||||
Smarty addTemplateDir( array|string $path, [string $index])
|
||||
replaces $smarty->template_dir[] = "bar"; and
|
||||
$smarty->template_dir[$index] = "bar";
|
||||
|
||||
array|string getConfigDir( [string $index] )
|
||||
replaces $smarty->config_dir; and $smarty->config_dir[$index];
|
||||
Smarty setConfigDir( array|string $path )
|
||||
replaces $smarty->config_dir = "foo"; and $smarty->config_dir =
|
||||
array("foo", "bar");
|
||||
Smarty addConfigDir( array|string $path, [string $index])
|
||||
replaces $smarty->config_dir[] = "bar"; and
|
||||
$smarty->config_dir[$index] = "bar";
|
||||
|
||||
array getPluginsDir()
|
||||
replaces $smarty->plugins_dir;
|
||||
Smarty setPluginsDir( array|string $path )
|
||||
replaces $smarty->plugins_dir = "foo";
|
||||
Smarty addPluginsDir( array|string $path )
|
||||
replaces $smarty->plugins_dir[] = "bar";
|
||||
|
||||
string getCompileDir()
|
||||
replaces $smarty->compile_dir;
|
||||
Smarty setCompileDir( string $path )
|
||||
replaces $smarty->compile_dir = "foo";
|
||||
|
||||
string getCacheDir()
|
||||
replaces $smarty->cache_dir;
|
||||
Smarty setCacheDir( string $path )
|
||||
replaces $smarty->cache_dir;
|
|
@ -5,7 +5,7 @@
|
|||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"homepage": "https://smarty-php.github.io/smarty/",
|
||||
"homepage": "http://www.smarty.net",
|
||||
"license": "LGPL-3.0",
|
||||
"authors": [
|
||||
{
|
||||
|
@ -19,35 +19,28 @@
|
|||
{
|
||||
"name": "Rodney Rehm",
|
||||
"email": "rodney.rehm@medialize.de"
|
||||
},
|
||||
{
|
||||
"name": "Simon Wisselink",
|
||||
"homepage": "https://www.iwink.nl/"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/smarty",
|
||||
"issues": "https://github.com/smarty-php/smarty/issues",
|
||||
"forum": "https://github.com/smarty-php/smarty/discussions"
|
||||
"forum": "http://www.smarty.net/forums/"
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"symfony/polyfill-mbstring": "^1.27"
|
||||
"php": "^5.2 || ^7.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4" : {
|
||||
"Smarty\\" : "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
"classmap": [
|
||||
"libs/"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.0.x-dev"
|
||||
"dev-master": "3.1.x-dev"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5 || ^7.5",
|
||||
"smarty/smarty-lexer": "^4.0.2"
|
||||
"phpunit/phpunit": "^7.5 || ^6.5 || ^5.7 || ^4.8",
|
||||
"smarty/smarty-lexer": "^3.1"
|
||||
}
|
||||
}
|
|
@ -2,11 +2,11 @@
|
|||
/**
|
||||
* Example Application
|
||||
*
|
||||
|
||||
* @package Example-application
|
||||
*/
|
||||
|
||||
$smarty = new \Smarty\Smarty;
|
||||
|
||||
require '../libs/Smarty.class.php';
|
||||
$smarty = new Smarty;
|
||||
//$smarty->force_compile = true;
|
||||
$smarty->debugging = true;
|
||||
$smarty->caching = true;
|
||||
$smarty->cache_lifetime = 120;
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* APC CacheResource
|
||||
* CacheResource Implementation based on the KeyValueStore API to use
|
||||
* memcache as the storage resource for Smarty's output caching.
|
||||
* *
|
||||
*
|
||||
* @package CacheResource-examples
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
class Smarty_CacheResource_Apc extends Smarty_CacheResource_KeyValueStore
|
||||
{
|
||||
/**
|
||||
* Smarty_CacheResource_Apc constructor.
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// test if APC is present
|
||||
if (!function_exists('apc_cache_info')) {
|
||||
throw new Exception('APC Template Caching Error: APC is not installed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read values for a set of keys from cache
|
||||
*
|
||||
* @param array $keys list of keys to fetch
|
||||
*
|
||||
* @return array list of values with the given keys used as indexes
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
protected function read(array $keys)
|
||||
{
|
||||
$_res = array();
|
||||
$res = apc_fetch($keys);
|
||||
foreach ($res as $k => $v) {
|
||||
$_res[ $k ] = $v;
|
||||
}
|
||||
return $_res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save values for a set of keys to cache
|
||||
*
|
||||
* @param array $keys list of values to save
|
||||
* @param int $expire expiration time
|
||||
*
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
protected function write(array $keys, $expire = null)
|
||||
{
|
||||
foreach ($keys as $k => $v) {
|
||||
apc_store($k, $v, $expire);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove values from cache
|
||||
*
|
||||
* @param array $keys list of keys to delete
|
||||
*
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
protected function delete(array $keys)
|
||||
{
|
||||
foreach ($keys as $k) {
|
||||
apc_delete($k);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove *all* values from cache
|
||||
*
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
protected function purge()
|
||||
{
|
||||
return apc_clear_cache('user');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Memcache CacheResource
|
||||
* CacheResource Implementation based on the KeyValueStore API to use
|
||||
* memcache as the storage resource for Smarty's output caching.
|
||||
* Note that memcache has a limitation of 256 characters per cache-key.
|
||||
* To avoid complications all cache-keys are translated to a sha1 hash.
|
||||
*
|
||||
* @package CacheResource-examples
|
||||
* @author Rodney Rehm
|
||||
*/
|
||||
class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore
|
||||
{
|
||||
/**
|
||||
* memcache instance
|
||||
*
|
||||
* @var Memcache
|
||||
*/
|
||||
protected $memcache = null;
|
||||
|
||||
/**
|
||||
* Smarty_CacheResource_Memcache constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (class_exists('Memcached')) {
|
||||
$this->memcache = new Memcached();
|
||||
} else {
|
||||
$this->memcache = new Memcache();
|
||||
}
|
||||
$this->memcache->addServer('127.0.0.1', 11211);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read values for a set of keys from cache
|
||||
*
|
||||
* @param array $keys list of keys to fetch
|
||||
*
|
||||
* @return array list of values with the given keys used as indexes
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
protected function read(array $keys)
|
||||
{
|
||||
$res = array();
|
||||
foreach ($keys as $key) {
|
||||
$k = sha1($key);
|
||||
$res[$key] = $this->memcache->get($k);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save values for a set of keys to cache
|
||||
*
|
||||
* @param array $keys list of values to save
|
||||
* @param int $expire expiration time
|
||||
*
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
protected function write(array $keys, $expire = null)
|
||||
{
|
||||
foreach ($keys as $k => $v) {
|
||||
$k = sha1($k);
|
||||
if (class_exists('Memcached')) {
|
||||
$this->memcache->set($k, $v, $expire);
|
||||
} else {
|
||||
$this->memcache->set($k, $v, 0, $expire);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove values from cache
|
||||
*
|
||||
* @param array $keys list of keys to delete
|
||||
*
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
protected function delete(array $keys)
|
||||
{
|
||||
foreach ($keys as $k) {
|
||||
$k = sha1($k);
|
||||
$this->memcache->delete($k);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove *all* values from cache
|
||||
*
|
||||
* @return boolean true on success, false on failure
|
||||
*/
|
||||
protected function purge()
|
||||
{
|
||||
return $this->memcache->flush();
|
||||
}
|
||||
}
|
183
src/includes/smarty-3.1.48/demo/plugins/cacheresource.mysql.php
Normal file
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* MySQL CacheResource
|
||||
* CacheResource Implementation based on the Custom API to use
|
||||
* MySQL as the storage resource for Smarty's output caching.
|
||||
* Table definition:
|
||||
* <pre>CREATE TABLE IF NOT EXISTS `output_cache` (
|
||||
* `id` CHAR(40) NOT NULL COMMENT 'sha1 hash',
|
||||
* `name` VARCHAR(250) NOT NULL,
|
||||
* `cache_id` VARCHAR(250) NULL DEFAULT NULL,
|
||||
* `compile_id` VARCHAR(250) NULL DEFAULT NULL,
|
||||
* `modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
* `content` LONGTEXT NOT NULL,
|
||||
* PRIMARY KEY (`id`),
|
||||
* INDEX(`name`),
|
||||
* INDEX(`cache_id`),
|
||||
* INDEX(`compile_id`),
|
||||
* INDEX(`modified`)
|
||||
* ) ENGINE = InnoDB;</pre>
|
||||
*
|
||||
* @package CacheResource-examples
|
||||
* @author Rodney Rehm
|
||||
*/
|
||||
class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom
|
||||
{
|
||||
/**
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* @var \PDOStatement
|
||||
*/
|
||||
protected $fetch;
|
||||
|
||||
/**
|
||||
* @var \PDOStatement
|
||||
*/
|
||||
protected $fetchTimestamp;
|
||||
|
||||
/**
|
||||
* @var \PDOStatement
|
||||
*/
|
||||
protected $save;
|
||||
|
||||
/**
|
||||
* Smarty_CacheResource_Mysql constructor.
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
try {
|
||||
$this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty");
|
||||
} catch (PDOException $e) {
|
||||
throw new SmartyException('Mysql Resource failed: ' . $e->getMessage());
|
||||
}
|
||||
$this->fetch = $this->db->prepare('SELECT modified, content FROM output_cache WHERE id = :id');
|
||||
$this->fetchTimestamp = $this->db->prepare('SELECT modified FROM output_cache WHERE id = :id');
|
||||
$this->save = $this->db->prepare(
|
||||
'REPLACE INTO output_cache (id, name, cache_id, compile_id, content)
|
||||
VALUES (:id, :name, :cache_id, :compile_id, :content)'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch cached content and its modification time from data source
|
||||
*
|
||||
* @param string $id unique cache content identifier
|
||||
* @param string $name template name
|
||||
* @param string $cache_id cache id
|
||||
* @param string $compile_id compile id
|
||||
* @param string $content cached content
|
||||
* @param integer $mtime cache modification timestamp (epoch)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime)
|
||||
{
|
||||
$this->fetch->execute(array('id' => $id));
|
||||
$row = $this->fetch->fetch();
|
||||
$this->fetch->closeCursor();
|
||||
if ($row) {
|
||||
$content = $row[ 'content' ];
|
||||
$mtime = strtotime($row[ 'modified' ]);
|
||||
} else {
|
||||
$content = null;
|
||||
$mtime = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch cached content's modification timestamp from data source
|
||||
*
|
||||
* @note implementing this method is optional. Only implement it if modification times can be accessed faster than
|
||||
* loading the complete cached content.
|
||||
*
|
||||
* @param string $id unique cache content identifier
|
||||
* @param string $name template name
|
||||
* @param string $cache_id cache id
|
||||
* @param string $compile_id compile id
|
||||
*
|
||||
* @return integer|boolean timestamp (epoch) the template was modified, or false if not found
|
||||
*/
|
||||
protected function fetchTimestamp($id, $name, $cache_id, $compile_id)
|
||||
{
|
||||
$this->fetchTimestamp->execute(array('id' => $id));
|
||||
$mtime = strtotime($this->fetchTimestamp->fetchColumn());
|
||||
$this->fetchTimestamp->closeCursor();
|
||||
return $mtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save content to cache
|
||||
*
|
||||
* @param string $id unique cache content identifier
|
||||
* @param string $name template name
|
||||
* @param string $cache_id cache id
|
||||
* @param string $compile_id compile id
|
||||
* @param integer|null $exp_time seconds till expiration time in seconds or null
|
||||
* @param string $content content to cache
|
||||
*
|
||||
* @return boolean success
|
||||
*/
|
||||
protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content)
|
||||
{
|
||||
$this->save->execute(
|
||||
array('id' => $id,
|
||||
'name' => $name,
|
||||
'cache_id' => $cache_id,
|
||||
'compile_id' => $compile_id,
|
||||
'content' => $content,)
|
||||
);
|
||||
return !!$this->save->rowCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete content from cache
|
||||
*
|
||||
* @param string $name template name
|
||||
* @param string $cache_id cache id
|
||||
* @param string $compile_id compile id
|
||||
* @param integer|null $exp_time seconds till expiration or null
|
||||
*
|
||||
* @return integer number of deleted caches
|
||||
*/
|
||||
protected function delete($name, $cache_id, $compile_id, $exp_time)
|
||||
{
|
||||
// delete the whole cache
|
||||
if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
|
||||
// returning the number of deleted caches would require a second query to count them
|
||||
$query = $this->db->query('TRUNCATE TABLE output_cache');
|
||||
return -1;
|
||||
}
|
||||
// build the filter
|
||||
$where = array();
|
||||
// equal test name
|
||||
if ($name !== null) {
|
||||
$where[] = 'name = ' . $this->db->quote($name);
|
||||
}
|
||||
// equal test compile_id
|
||||
if ($compile_id !== null) {
|
||||
$where[] = 'compile_id = ' . $this->db->quote($compile_id);
|
||||
}
|
||||
// range test expiration time
|
||||
if ($exp_time !== null) {
|
||||
$where[] = 'modified < DATE_SUB(NOW(), INTERVAL ' . intval($exp_time) . ' SECOND)';
|
||||
}
|
||||
// equal test cache_id and match sub-groups
|
||||
if ($cache_id !== null) {
|
||||
$where[] =
|
||||
'(cache_id = ' .
|
||||
$this->db->quote($cache_id) .
|
||||
' OR cache_id LIKE ' .
|
||||
$this->db->quote($cache_id . '|%') .
|
||||
')';
|
||||
}
|
||||
// run delete query
|
||||
$query = $this->db->query('DELETE FROM output_cache WHERE ' . join(' AND ', $where));
|
||||
return $query->rowCount();
|
||||
}
|
||||
}
|
346
src/includes/smarty-3.1.48/demo/plugins/cacheresource.pdo.php
Normal file
|
@ -0,0 +1,346 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PDO Cache Handler
|
||||
* Allows you to store Smarty Cache files into your db.
|
||||
* Example table :
|
||||
* CREATE TABLE `smarty_cache` (
|
||||
* `id` char(40) NOT NULL COMMENT 'sha1 hash',
|
||||
* `name` varchar(250) NOT NULL,
|
||||
* `cache_id` varchar(250) DEFAULT NULL,
|
||||
* `compile_id` varchar(250) DEFAULT NULL,
|
||||
* `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
* `expire` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
* `content` mediumblob NOT NULL,
|
||||
* PRIMARY KEY (`id`),
|
||||
* KEY `name` (`name`),
|
||||
* KEY `cache_id` (`cache_id`),
|
||||
* KEY `compile_id` (`compile_id`),
|
||||
* KEY `modified` (`modified`),
|
||||
* KEY `expire` (`expire`)
|
||||
* ) ENGINE=InnoDB
|
||||
* Example usage :
|
||||
* $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
|
||||
* $smarty->setCachingType('pdo');
|
||||
* $smarty->loadPlugin('Smarty_CacheResource_Pdo');
|
||||
* $smarty->registerCacheResource('pdo', new Smarty_CacheResource_Pdo($cnx, 'smarty_cache'));
|
||||
*
|
||||
* @author Beno!t POLASZEK - 2014
|
||||
*/
|
||||
class Smarty_CacheResource_Pdo extends Smarty_CacheResource_Custom
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fetchStatements = array('default' => 'SELECT %2$s
|
||||
FROM %1$s
|
||||
WHERE 1
|
||||
AND id = :id
|
||||
AND cache_id IS NULL
|
||||
AND compile_id IS NULL',
|
||||
'withCacheId' => 'SELECT %2$s
|
||||
FROM %1$s
|
||||
WHERE 1
|
||||
AND id = :id
|
||||
AND cache_id = :cache_id
|
||||
AND compile_id IS NULL',
|
||||
'withCompileId' => 'SELECT %2$s
|
||||
FROM %1$s
|
||||
WHERE 1
|
||||
AND id = :id
|
||||
AND compile_id = :compile_id
|
||||
AND cache_id IS NULL',
|
||||
'withCacheIdAndCompileId' => 'SELECT %2$s
|
||||
FROM %1$s
|
||||
WHERE 1
|
||||
AND id = :id
|
||||
AND cache_id = :cache_id
|
||||
AND compile_id = :compile_id');
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $insertStatement = 'INSERT INTO %s
|
||||
|
||||
SET id = :id,
|
||||
name = :name,
|
||||
cache_id = :cache_id,
|
||||
compile_id = :compile_id,
|
||||
modified = CURRENT_TIMESTAMP,
|
||||
expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
|
||||
content = :content
|
||||
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = :name,
|
||||
cache_id = :cache_id,
|
||||
compile_id = :compile_id,
|
||||
modified = CURRENT_TIMESTAMP,
|
||||
expire = DATE_ADD(CURRENT_TIMESTAMP, INTERVAL :expire SECOND),
|
||||
content = :content';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $deleteStatement = 'DELETE FROM %1$s WHERE %2$s';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $truncateStatement = 'TRUNCATE TABLE %s';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fetchColumns = 'modified, content';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $fetchTimestampColumns = 'modified';
|
||||
|
||||
/**
|
||||
* @var \PDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $table;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PDO $pdo PDO : active connection
|
||||
* @param string $table : table (or view) name
|
||||
* @param string $database : optional - if table is located in another db
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function __construct(PDO $pdo, $table, $database = null)
|
||||
{
|
||||
if (is_null($table)) {
|
||||
throw new SmartyException("Table name for caching can't be null");
|
||||
}
|
||||
$this->pdo = $pdo;
|
||||
$this->table = $table;
|
||||
$this->database = $database;
|
||||
$this->fillStatementsWithTableName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the table name into the statements.
|
||||
*
|
||||
* @return $this Current Instance
|
||||
* @access protected
|
||||
*/
|
||||
protected function fillStatementsWithTableName()
|
||||
{
|
||||
foreach ($this->fetchStatements as &$statement) {
|
||||
$statement = sprintf($statement, $this->getTableName(), '%s');
|
||||
}
|
||||
$this->insertStatement = sprintf($this->insertStatement, $this->getTableName());
|
||||
$this->deleteStatement = sprintf($this->deleteStatement, $this->getTableName(), '%s');
|
||||
$this->truncateStatement = sprintf($this->truncateStatement, $this->getTableName());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fetch statement, depending on what you specify
|
||||
*
|
||||
* @param string $columns : the column(s) name(s) you want to retrieve from the database
|
||||
* @param string $id unique cache content identifier
|
||||
* @param string|null $cache_id cache id
|
||||
* @param string|null $compile_id compile id
|
||||
*
|
||||
* @access protected
|
||||
* @return \PDOStatement
|
||||
*/
|
||||
protected function getFetchStatement($columns, $id, $cache_id = null, $compile_id = null)
|
||||
{
|
||||
$args = array();
|
||||
if (!is_null($cache_id) && !is_null($compile_id)) {
|
||||
$query = $this->fetchStatements[ 'withCacheIdAndCompileId' ] and
|
||||
$args = array('id' => $id, 'cache_id' => $cache_id, 'compile_id' => $compile_id);
|
||||
} elseif (is_null($cache_id) && !is_null($compile_id)) {
|
||||
$query = $this->fetchStatements[ 'withCompileId' ] and
|
||||
$args = array('id' => $id, 'compile_id' => $compile_id);
|
||||
} elseif (!is_null($cache_id) && is_null($compile_id)) {
|
||||
$query = $this->fetchStatements[ 'withCacheId' ] and $args = array('id' => $id, 'cache_id' => $cache_id);
|
||||
} else {
|
||||
$query = $this->fetchStatements[ 'default' ] and $args = array('id' => $id);
|
||||
}
|
||||
$query = sprintf($query, $columns);
|
||||
$stmt = $this->pdo->prepare($query);
|
||||
foreach ($args as $key => $value) {
|
||||
$stmt->bindValue($key, $value);
|
||||
}
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch cached content and its modification time from data source
|
||||
*
|
||||
* @param string $id unique cache content identifier
|
||||
* @param string $name template name
|
||||
* @param string|null $cache_id cache id
|
||||
* @param string|null $compile_id compile id
|
||||
* @param string $content cached content
|
||||
* @param integer $mtime cache modification timestamp (epoch)
|
||||
*
|
||||
* @return void
|
||||
* @access protected
|
||||
*/
|
||||
protected function fetch($id, $name, $cache_id = null, $compile_id = null, &$content, &$mtime)
|
||||
{
|
||||
$stmt = $this->getFetchStatement($this->fetchColumns, $id, $cache_id, $compile_id);
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch();
|
||||
$stmt->closeCursor();
|
||||
if ($row) {
|
||||
$content = $this->outputContent($row[ 'content' ]);
|
||||
$mtime = strtotime($row[ 'modified' ]);
|
||||
} else {
|
||||
$content = null;
|
||||
$mtime = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch cached content's modification timestamp from data source
|
||||
* {@internal implementing this method is optional.
|
||||
* Only implement it if modification times can be accessed faster than loading the complete cached content.}}
|
||||
*
|
||||
* @param string $id unique cache content identifier
|
||||
* @param string $name template name
|
||||
* @param string|null $cache_id cache id
|
||||
* @param string|null $compile_id compile id
|
||||
*
|
||||
* @return integer|boolean timestamp (epoch) the template was modified, or false if not found
|
||||
* @access protected
|
||||
*/
|
||||
// protected function fetchTimestamp($id, $name, $cache_id = null, $compile_id = null) {
|
||||
// $stmt = $this->getFetchStatement($this->fetchTimestampColumns, $id, $cache_id, $compile_id);
|
||||
// $stmt -> execute();
|
||||
// $mtime = strtotime($stmt->fetchColumn());
|
||||
// $stmt -> closeCursor();
|
||||
// return $mtime;
|
||||
// }
|
||||
/**
|
||||
* Save content to cache
|
||||
*
|
||||
* @param string $id unique cache content identifier
|
||||
* @param string $name template name
|
||||
* @param string|null $cache_id cache id
|
||||
* @param string|null $compile_id compile id
|
||||
* @param integer|null $exp_time seconds till expiration time in seconds or null
|
||||
* @param string $content content to cache
|
||||
*
|
||||
* @return boolean success
|
||||
* @access protected
|
||||
*/
|
||||
protected function save($id, $name, $cache_id = null, $compile_id = null, $exp_time, $content)
|
||||
{
|
||||
$stmt = $this->pdo->prepare($this->insertStatement);
|
||||
$stmt->bindValue('id', $id);
|
||||
$stmt->bindValue('name', $name);
|
||||
$stmt->bindValue('cache_id', $cache_id, (is_null($cache_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
|
||||
$stmt->bindValue('compile_id', $compile_id, (is_null($compile_id)) ? PDO::PARAM_NULL : PDO::PARAM_STR);
|
||||
$stmt->bindValue('expire', (int)$exp_time, PDO::PARAM_INT);
|
||||
$stmt->bindValue('content', $this->inputContent($content));
|
||||
$stmt->execute();
|
||||
return !!$stmt->rowCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the content before saving to database
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return string $content
|
||||
* @access protected
|
||||
*/
|
||||
protected function inputContent($content)
|
||||
{
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the content before saving to database
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return string $content
|
||||
* @access protected
|
||||
*/
|
||||
protected function outputContent($content)
|
||||
{
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete content from cache
|
||||
*
|
||||
* @param string|null $name template name
|
||||
* @param string|null $cache_id cache id
|
||||
* @param string|null $compile_id compile id
|
||||
* @param integer|null|-1 $exp_time seconds till expiration or null
|
||||
*
|
||||
* @return integer number of deleted caches
|
||||
* @access protected
|
||||
*/
|
||||
protected function delete($name = null, $cache_id = null, $compile_id = null, $exp_time = null)
|
||||
{
|
||||
// delete the whole cache
|
||||
if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
|
||||
// returning the number of deleted caches would require a second query to count them
|
||||
$this->pdo->query($this->truncateStatement);
|
||||
return -1;
|
||||
}
|
||||
// build the filter
|
||||
$where = array();
|
||||
// equal test name
|
||||
if ($name !== null) {
|
||||
$where[] = 'name = ' . $this->pdo->quote($name);
|
||||
}
|
||||
// equal test cache_id and match sub-groups
|
||||
if ($cache_id !== null) {
|
||||
$where[] =
|
||||
'(cache_id = ' .
|
||||
$this->pdo->quote($cache_id) .
|
||||
' OR cache_id LIKE ' .
|
||||
$this->pdo->quote($cache_id . '|%') .
|
||||
')';
|
||||
}
|
||||
// equal test compile_id
|
||||
if ($compile_id !== null) {
|
||||
$where[] = 'compile_id = ' . $this->pdo->quote($compile_id);
|
||||
}
|
||||
// for clearing expired caches
|
||||
if ($exp_time === Smarty::CLEAR_EXPIRED) {
|
||||
$where[] = 'expire < CURRENT_TIMESTAMP';
|
||||
} // range test expiration time
|
||||
elseif ($exp_time !== null) {
|
||||
$where[] = 'modified < DATE_SUB(NOW(), INTERVAL ' . intval($exp_time) . ' SECOND)';
|
||||
}
|
||||
// run delete query
|
||||
$query = $this->pdo->query(sprintf($this->deleteStatement, join(' AND ', $where)));
|
||||
return $query->rowCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatted table name
|
||||
*
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
protected function getTableName()
|
||||
{
|
||||
return (is_null($this->database)) ? "`{$this->table}`" : "`{$this->database}`.`{$this->table}`";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
require_once 'cacheresource.pdo.php';
|
||||
|
||||
/**
|
||||
* PDO Cache Handler with GZIP support
|
||||
* Example usage :
|
||||
* $cnx = new PDO("mysql:host=localhost;dbname=mydb", "username", "password");
|
||||
* $smarty->setCachingType('pdo_gzip');
|
||||
* $smarty->loadPlugin('Smarty_CacheResource_Pdo_Gzip');
|
||||
* $smarty->registerCacheResource('pdo_gzip', new Smarty_CacheResource_Pdo_Gzip($cnx, 'smarty_cache'));
|
||||
*
|
||||
* @require Smarty_CacheResource_Pdo class
|
||||
* @author Beno!t POLASZEK - 2014
|
||||
*/
|
||||
class Smarty_CacheResource_Pdo_Gzip extends Smarty_CacheResource_Pdo
|
||||
{
|
||||
/**
|
||||
* Encodes the content before saving to database
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return string $content
|
||||
* @access protected
|
||||
*/
|
||||
protected function inputContent($content)
|
||||
{
|
||||
return gzdeflate($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the content before saving to database
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return string $content
|
||||
* @access protected
|
||||
*/
|
||||
protected function outputContent($content)
|
||||
{
|
||||
return gzinflate($content);
|
||||
}
|
||||
}
|