Automated build for v0.01
This commit is contained in:
26
include/autoload.php
Normal file
26
include/autoload.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
require_once "functions.php";
|
||||
|
||||
spl_autoload_register(function($class) {
|
||||
$namespace = '';
|
||||
$class_name = $class;
|
||||
|
||||
if (strpos($class, '\\') !== FALSE)
|
||||
list ($namespace, $class_name) = explode('\\', $class, 2);
|
||||
|
||||
$root_dir = dirname(__DIR__); // we're in tt-rss/include
|
||||
|
||||
// 1. third party libraries with namespaces are loaded from vendor/
|
||||
// 2. internal tt-rss classes are loaded from classes/ and use special naming logic instead of namespaces
|
||||
// 3. plugin classes are loaded by PluginHandler from plugins.local/ and plugins/ (TODO: use generic autoloader?)
|
||||
|
||||
if ($namespace && $class_name) {
|
||||
$class_file = "$root_dir/vendor/$namespace/" . str_replace('\\', '/', $class_name) . ".php";
|
||||
} else {
|
||||
$class_file = "$root_dir/classes/" . str_replace("_", "/", strtolower($class)) . ".php";
|
||||
}
|
||||
|
||||
if (file_exists($class_file))
|
||||
include $class_file;
|
||||
|
||||
});
|
351
include/colors.php
Normal file
351
include/colors.php
Normal file
@ -0,0 +1,351 @@
|
||||
<?php
|
||||
|
||||
if (file_exists("lib/floIcon.php")) {
|
||||
require_once "lib/floIcon.php";
|
||||
}
|
||||
|
||||
function _resolve_htmlcolor($color) {
|
||||
$htmlcolors = array ("aliceblue" => "#f0f8ff",
|
||||
"antiquewhite" => "#faebd7",
|
||||
"aqua" => "#00ffff",
|
||||
"aquamarine" => "#7fffd4",
|
||||
"azure" => "#f0ffff",
|
||||
"beige" => "#f5f5dc",
|
||||
"bisque" => "#ffe4c4",
|
||||
"black" => "#000000",
|
||||
"blanchedalmond" => "#ffebcd",
|
||||
"blue" => "#0000ff",
|
||||
"blueviolet" => "#8a2be2",
|
||||
"brown" => "#a52a2a",
|
||||
"burlywood" => "#deb887",
|
||||
"cadetblue" => "#5f9ea0",
|
||||
"chartreuse" => "#7fff00",
|
||||
"chocolate" => "#d2691e",
|
||||
"coral" => "#ff7f50",
|
||||
"cornflowerblue" => "#6495ed",
|
||||
"cornsilk" => "#fff8dc",
|
||||
"crimson" => "#dc143c",
|
||||
"cyan" => "#00ffff",
|
||||
"darkblue" => "#00008b",
|
||||
"darkcyan" => "#008b8b",
|
||||
"darkgoldenrod" => "#b8860b",
|
||||
"darkgray" => "#a9a9a9",
|
||||
"darkgrey" => "#a9a9a9",
|
||||
"darkgreen" => "#006400",
|
||||
"darkkhaki" => "#bdb76b",
|
||||
"darkmagenta" => "#8b008b",
|
||||
"darkolivegreen" => "#556b2f",
|
||||
"darkorange" => "#ff8c00",
|
||||
"darkorchid" => "#9932cc",
|
||||
"darkred" => "#8b0000",
|
||||
"darksalmon" => "#e9967a",
|
||||
"darkseagreen" => "#8fbc8f",
|
||||
"darkslateblue" => "#483d8b",
|
||||
"darkslategray" => "#2f4f4f",
|
||||
"darkslategrey" => "#2f4f4f",
|
||||
"darkturquoise" => "#00ced1",
|
||||
"darkviolet" => "#9400d3",
|
||||
"deeppink" => "#ff1493",
|
||||
"deepskyblue" => "#00bfff",
|
||||
"dimgray" => "#696969",
|
||||
"dimgrey" => "#696969",
|
||||
"dodgerblue" => "#1e90ff",
|
||||
"firebrick" => "#b22222",
|
||||
"floralwhite" => "#fffaf0",
|
||||
"forestgreen" => "#228b22",
|
||||
"fuchsia" => "#ff00ff",
|
||||
"gainsboro" => "#dcdcdc",
|
||||
"ghostwhite" => "#f8f8ff",
|
||||
"gold" => "#ffd700",
|
||||
"goldenrod" => "#daa520",
|
||||
"gray" => "#808080",
|
||||
"grey" => "#808080",
|
||||
"green" => "#008000",
|
||||
"greenyellow" => "#adff2f",
|
||||
"honeydew" => "#f0fff0",
|
||||
"hotpink" => "#ff69b4",
|
||||
"indianred " => "#cd5c5c",
|
||||
"indigo " => "#4b0082",
|
||||
"ivory" => "#fffff0",
|
||||
"khaki" => "#f0e68c",
|
||||
"lavender" => "#e6e6fa",
|
||||
"lavenderblush" => "#fff0f5",
|
||||
"lawngreen" => "#7cfc00",
|
||||
"lemonchiffon" => "#fffacd",
|
||||
"lightblue" => "#add8e6",
|
||||
"lightcoral" => "#f08080",
|
||||
"lightcyan" => "#e0ffff",
|
||||
"lightgoldenrodyellow" => "#fafad2",
|
||||
"lightgray" => "#d3d3d3",
|
||||
"lightgrey" => "#d3d3d3",
|
||||
"lightgreen" => "#90ee90",
|
||||
"lightpink" => "#ffb6c1",
|
||||
"lightsalmon" => "#ffa07a",
|
||||
"lightseagreen" => "#20b2aa",
|
||||
"lightskyblue" => "#87cefa",
|
||||
"lightslategray" => "#778899",
|
||||
"lightslategrey" => "#778899",
|
||||
"lightsteelblue" => "#b0c4de",
|
||||
"lightyellow" => "#ffffe0",
|
||||
"lime" => "#00ff00",
|
||||
"limegreen" => "#32cd32",
|
||||
"linen" => "#faf0e6",
|
||||
"magenta" => "#ff00ff",
|
||||
"maroon" => "#800000",
|
||||
"mediumaquamarine" => "#66cdaa",
|
||||
"mediumblue" => "#0000cd",
|
||||
"mediumorchid" => "#ba55d3",
|
||||
"mediumpurple" => "#9370db",
|
||||
"mediumseagreen" => "#3cb371",
|
||||
"mediumslateblue" => "#7b68ee",
|
||||
"mediumspringgreen" => "#00fa9a",
|
||||
"mediumturquoise" => "#48d1cc",
|
||||
"mediumvioletred" => "#c71585",
|
||||
"midnightblue" => "#191970",
|
||||
"mintcream" => "#f5fffa",
|
||||
"mistyrose" => "#ffe4e1",
|
||||
"moccasin" => "#ffe4b5",
|
||||
"navajowhite" => "#ffdead",
|
||||
"navy" => "#000080",
|
||||
"oldlace" => "#fdf5e6",
|
||||
"olive" => "#808000",
|
||||
"olivedrab" => "#6b8e23",
|
||||
"orange" => "#ffa500",
|
||||
"orangered" => "#ff4500",
|
||||
"orchid" => "#da70d6",
|
||||
"palegoldenrod" => "#eee8aa",
|
||||
"palegreen" => "#98fb98",
|
||||
"paleturquoise" => "#afeeee",
|
||||
"palevioletred" => "#db7093",
|
||||
"papayawhip" => "#ffefd5",
|
||||
"peachpuff" => "#ffdab9",
|
||||
"peru" => "#cd853f",
|
||||
"pink" => "#ffc0cb",
|
||||
"plum" => "#dda0dd",
|
||||
"powderblue" => "#b0e0e6",
|
||||
"purple" => "#800080",
|
||||
"red" => "#ff0000",
|
||||
"rosybrown" => "#bc8f8f",
|
||||
"royalblue" => "#4169e1",
|
||||
"saddlebrown" => "#8b4513",
|
||||
"salmon" => "#fa8072",
|
||||
"sandybrown" => "#f4a460",
|
||||
"seagreen" => "#2e8b57",
|
||||
"seashell" => "#fff5ee",
|
||||
"sienna" => "#a0522d",
|
||||
"silver" => "#c0c0c0",
|
||||
"skyblue" => "#87ceeb",
|
||||
"slateblue" => "#6a5acd",
|
||||
"slategray" => "#708090",
|
||||
"slategrey" => "#708090",
|
||||
"snow" => "#fffafa",
|
||||
"springgreen" => "#00ff7f",
|
||||
"steelblue" => "#4682b4",
|
||||
"tan" => "#d2b48c",
|
||||
"teal" => "#008080",
|
||||
"thistle" => "#d8bfd8",
|
||||
"tomato" => "#ff6347",
|
||||
"turquoise" => "#40e0d0",
|
||||
"violet" => "#ee82ee",
|
||||
"wheat" => "#f5deb3",
|
||||
"white" => "#ffffff",
|
||||
"whitesmoke" => "#f5f5f5",
|
||||
"yellow" => "#ffff00",
|
||||
"yellowgreen" => "#9acd32");
|
||||
|
||||
$color = strtolower($color);
|
||||
|
||||
if (isset($htmlcolors[$color]))
|
||||
return $htmlcolors[$color];
|
||||
else
|
||||
return $color;
|
||||
}
|
||||
|
||||
### RGB >> HSL
|
||||
function _color_rgb2hsl($rgb) {
|
||||
$r = $rgb[0]; $g = $rgb[1]; $b = $rgb[2];
|
||||
$min = min($r, min($g, $b)); $max = max($r, max($g, $b));
|
||||
$delta = $max - $min; $l = ($min + $max) / 2; $s = 0;
|
||||
if ($l > 0 && $l < 1) {
|
||||
$s = $delta / ($l < 0.5 ? (2 * $l) : (2 - 2 * $l));
|
||||
}
|
||||
$h = 0;
|
||||
if ($delta > 0) {
|
||||
if ($max == $r && $max != $g) $h += ($g - $b) / $delta;
|
||||
if ($max == $g && $max != $b) $h += (2 + ($b - $r) / $delta);
|
||||
if ($max == $b && $max != $r) $h += (4 + ($r - $g) / $delta);
|
||||
$h /= 6;
|
||||
} return array($h, $s, $l);
|
||||
}
|
||||
|
||||
### HSL >> RGB
|
||||
function _color_hsl2rgb($hsl) {
|
||||
$h = $hsl[0]; $s = $hsl[1]; $l = $hsl[2];
|
||||
$m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l*$s;
|
||||
$m1 = $l * 2 - $m2;
|
||||
return array(_color_hue2rgb($m1, $m2, $h + 0.33333),
|
||||
_color_hue2rgb($m1, $m2, $h),
|
||||
_color_hue2rgb($m1, $m2, $h - 0.33333));
|
||||
}
|
||||
|
||||
### Helper function for _color_hsl2rgb().
|
||||
function _color_hue2rgb($m1, $m2, $h) {
|
||||
$h = ($h < 0) ? $h + 1 : (($h > 1) ? $h - 1 : $h);
|
||||
if ($h * 6 < 1) return $m1 + ($m2 - $m1) * $h * 6;
|
||||
if ($h * 2 < 1) return $m2;
|
||||
if ($h * 3 < 2) return $m1 + ($m2 - $m1) * (0.66666 - $h) * 6;
|
||||
return $m1;
|
||||
}
|
||||
|
||||
### Convert a hex color into an RGB triplet.
|
||||
function _color_unpack($hex, $normalize = false) {
|
||||
|
||||
if (strpos($hex, '#') !== 0)
|
||||
$hex = _resolve_htmlcolor($hex);
|
||||
|
||||
if (strlen($hex) == 4) {
|
||||
$hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3];
|
||||
} $c = hexdec($hex);
|
||||
for ($i = 16; $i >= 0; $i -= 8) {
|
||||
$out[] = (($c >> $i) & 0xFF) / ($normalize ? 255 : 1);
|
||||
} return $out;
|
||||
}
|
||||
|
||||
### Convert an RGB triplet to a hex color.
|
||||
function _color_pack($rgb, $normalize = false) {
|
||||
foreach ($rgb as $k => $v) {
|
||||
$out |= (($v * ($normalize ? 255 : 1)) << (16 - $k * 8));
|
||||
}return '#'. str_pad(dechex($out), 6, 0, STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
function rgb2hsl($arr) {
|
||||
$r = $arr[0];
|
||||
$g = $arr[1];
|
||||
$b = $arr[2];
|
||||
|
||||
$var_R = ($r / 255);
|
||||
$var_G = ($g / 255);
|
||||
$var_B = ($b / 255);
|
||||
|
||||
$var_Min = min($var_R, $var_G, $var_B);
|
||||
$var_Max = max($var_R, $var_G, $var_B);
|
||||
$del_Max = $var_Max - $var_Min;
|
||||
|
||||
$v = $var_Max;
|
||||
|
||||
if ($del_Max == 0) {
|
||||
$h = 0;
|
||||
$s = 0;
|
||||
} else {
|
||||
$s = $del_Max / $var_Max;
|
||||
|
||||
$del_R = ((($var_Max - $var_R ) / 6 ) + ($del_Max / 2 ) ) / $del_Max;
|
||||
$del_G = ((($var_Max - $var_G ) / 6 ) + ($del_Max / 2 ) ) / $del_Max;
|
||||
$del_B = ((($var_Max - $var_B ) / 6 ) + ($del_Max / 2 ) ) / $del_Max;
|
||||
|
||||
if ($var_R == $var_Max) $h = $del_B - $del_G;
|
||||
else if ($var_G == $var_Max) $h = (1 / 3 ) + $del_R - $del_B;
|
||||
else if ($var_B == $var_Max) $h = (2 / 3 ) + $del_G - $del_R;
|
||||
|
||||
if ($h < 0) $h++;
|
||||
if ($h > 1) $h--;
|
||||
}
|
||||
|
||||
return array($h, $s, $v);
|
||||
}
|
||||
|
||||
function hsl2rgb($arr) {
|
||||
$h = $arr[0];
|
||||
$s = $arr[1];
|
||||
$v = $arr[2];
|
||||
|
||||
if($s == 0) {
|
||||
$r = $g = $B = $v * 255;
|
||||
} else {
|
||||
$var_H = $h * 6;
|
||||
$var_i = floor($var_H );
|
||||
$var_1 = $v * (1 - $s );
|
||||
$var_2 = $v * (1 - $s * ($var_H - $var_i ) );
|
||||
$var_3 = $v * (1 - $s * (1 - ($var_H - $var_i ) ) );
|
||||
|
||||
if ($var_i == 0) { $var_R = $v ; $var_G = $var_3 ; $var_B = $var_1 ; }
|
||||
else if ($var_i == 1) { $var_R = $var_2 ; $var_G = $v ; $var_B = $var_1 ; }
|
||||
else if ($var_i == 2) { $var_R = $var_1 ; $var_G = $v ; $var_B = $var_3 ; }
|
||||
else if ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2 ; $var_B = $v ; }
|
||||
else if ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1 ; $var_B = $v ; }
|
||||
else { $var_R = $v ; $var_G = $var_1 ; $var_B = $var_2 ; }
|
||||
|
||||
$r = $var_R * 255;
|
||||
$g = $var_G * 255;
|
||||
$B = $var_B * 255;
|
||||
}
|
||||
return array($r, $g, $B);
|
||||
}
|
||||
|
||||
function colorPalette($imageFile, $numColors, $granularity = 5) {
|
||||
$granularity = max(1, abs((int)$granularity));
|
||||
$colors = array();
|
||||
|
||||
$size = @getimagesize($imageFile);
|
||||
|
||||
// to enable .ico support place floIcon.php into lib/
|
||||
if (strtolower($size['mime']) == 'image/vnd.microsoft.icon') {
|
||||
|
||||
if (class_exists("floIcon")) {
|
||||
|
||||
$ico = new floIcon();
|
||||
@$ico->readICO($imageFile);
|
||||
|
||||
if(count($ico->images)==0)
|
||||
return false;
|
||||
else
|
||||
$img = @$ico->images[count($ico->images)-1]->getImageResource();
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if ($size[0] > 0 && $size[1] > 0) {
|
||||
$img = @imagecreatefromstring(file_get_contents($imageFile));
|
||||
}
|
||||
|
||||
if (!$img) return false;
|
||||
|
||||
for($x = 0; $x < $size[0]; $x += $granularity) {
|
||||
for($y = 0; $y < $size[1]; $y += $granularity) {
|
||||
$thisColor = imagecolorat($img, $x, $y);
|
||||
$rgb = imagecolorsforindex($img, $thisColor);
|
||||
$red = round(round(($rgb['red'] / 0x33)) * 0x33);
|
||||
$green = round(round(($rgb['green'] / 0x33)) * 0x33);
|
||||
$blue = round(round(($rgb['blue'] / 0x33)) * 0x33);
|
||||
$thisRGB = sprintf('%02X%02X%02X', $red, $green, $blue);
|
||||
if(array_key_exists($thisRGB, $colors)) {
|
||||
$colors[$thisRGB]++;
|
||||
} else{
|
||||
$colors[$thisRGB] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arsort($colors);
|
||||
return array_slice(array_keys($colors), 0, $numColors);
|
||||
}
|
||||
|
||||
function calculate_avg_color($iconFile) {
|
||||
$palette = colorPalette($iconFile, 4, 4);
|
||||
|
||||
if (is_array($palette)) {
|
||||
foreach ($palette as $p) {
|
||||
$hsl = rgb2hsl(_color_unpack("#$p"));
|
||||
|
||||
if ($hsl[1] > 0.25 && $hsl[2] > 0.25 &&
|
||||
!($hsl[0] >= 0 && $hsl[0] < 0.01 && $hsl[1] < 0.01) &&
|
||||
!($hsl[0] >= 0 && $hsl[0] < 0.01 && $hsl[2] > 0.99)) {
|
||||
|
||||
return _color_pack(hsl2rgb($hsl));
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
339
include/controls.php
Executable file
339
include/controls.php
Executable file
@ -0,0 +1,339 @@
|
||||
<?php
|
||||
|
||||
function print_select($id, $default, $values, $attributes = "", $name = "") {
|
||||
if (!$name) $name = $id;
|
||||
|
||||
print "<select name=\"$name\" id=\"$id\" $attributes>";
|
||||
foreach ($values as $v) {
|
||||
if ($v == $default)
|
||||
$sel = "selected=\"1\"";
|
||||
else
|
||||
$sel = "";
|
||||
|
||||
$v = trim($v);
|
||||
|
||||
print "<option value=\"$v\" $sel>$v</option>";
|
||||
}
|
||||
print "</select>";
|
||||
}
|
||||
|
||||
function print_select_hash($id, $default, $values, $attributes = "", $name = "") {
|
||||
if (!$name) $name = $id;
|
||||
|
||||
print "<select name=\"$name\" id='$id' $attributes>";
|
||||
foreach (array_keys($values) as $v) {
|
||||
if ($v == $default)
|
||||
$sel = 'selected="selected"';
|
||||
else
|
||||
$sel = "";
|
||||
|
||||
$v = trim($v);
|
||||
|
||||
print "<option $sel value=\"$v\">".$values[$v]."</option>";
|
||||
}
|
||||
|
||||
print "</select>";
|
||||
}
|
||||
|
||||
function print_hidden($name, $value) {
|
||||
print "<input dojoType=\"dijit.form.TextBox\" style=\"display : none\" name=\"$name\" value=\"$value\">";
|
||||
}
|
||||
|
||||
function print_checkbox($id, $checked, $value = "", $attributes = "") {
|
||||
$checked_str = $checked ? "checked" : "";
|
||||
$value_str = $value ? "value=\"$value\"" : "";
|
||||
|
||||
print "<input dojoType=\"dijit.form.CheckBox\" id=\"$id\" $value_str $checked_str $attributes name=\"$id\">";
|
||||
}
|
||||
|
||||
function print_button($type, $value, $attributes = "") {
|
||||
print "<p><button dojoType=\"dijit.form.Button\" $attributes type=\"$type\">$value</button>";
|
||||
}
|
||||
|
||||
function print_radio($id, $default, $true_is, $values, $attributes = "") {
|
||||
foreach ($values as $v) {
|
||||
|
||||
if ($v == $default)
|
||||
$sel = "checked";
|
||||
else
|
||||
$sel = "";
|
||||
|
||||
if ($v == $true_is) {
|
||||
$sel .= " value=\"1\"";
|
||||
} else {
|
||||
$sel .= " value=\"0\"";
|
||||
}
|
||||
|
||||
print "<input class=\"noborder\" dojoType=\"dijit.form.RadioButton\"
|
||||
type=\"radio\" $sel $attributes name=\"$id\"> $v ";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function print_feed_multi_select($id, $default_ids = [],
|
||||
$attributes = "", $include_all_feeds = true,
|
||||
$root_id = null, $nest_level = 0) {
|
||||
|
||||
$pdo = DB::pdo();
|
||||
|
||||
print_r(in_array("CAT:6",$default_ids));
|
||||
|
||||
if (!$root_id) {
|
||||
print "<select multiple=\true\" id=\"$id\" name=\"$id\" $attributes>";
|
||||
if ($include_all_feeds) {
|
||||
$is_selected = (in_array("0", $default_ids)) ? "selected=\"1\"" : "";
|
||||
print "<option $is_selected value=\"0\">".__('All feeds')."</option>";
|
||||
}
|
||||
}
|
||||
|
||||
if (get_pref('ENABLE_FEED_CATS')) {
|
||||
|
||||
if (!$root_id) $root_id = null;
|
||||
|
||||
$sth = $pdo->prepare("SELECT id,title,
|
||||
(SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
|
||||
c2.parent_cat = ttrss_feed_categories.id) AS num_children
|
||||
FROM ttrss_feed_categories
|
||||
WHERE owner_uid = :uid AND
|
||||
(parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
|
||||
|
||||
$sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
|
||||
|
||||
while ($line = $sth->fetch()) {
|
||||
|
||||
for ($i = 0; $i < $nest_level; $i++)
|
||||
$line["title"] = " - " . $line["title"];
|
||||
|
||||
$is_selected = in_array("CAT:".$line["id"], $default_ids) ? "selected=\"1\"" : "";
|
||||
|
||||
printf("<option $is_selected value='CAT:%d'>%s</option>",
|
||||
$line["id"], htmlspecialchars($line["title"]));
|
||||
|
||||
if ($line["num_children"] > 0)
|
||||
print_feed_multi_select($id, $default_ids, $attributes,
|
||||
$include_all_feeds, $line["id"], $nest_level+1);
|
||||
|
||||
$f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
|
||||
WHERE cat_id = ? AND owner_uid = ? ORDER BY title");
|
||||
|
||||
$f_sth->execute([$line['id'], $_SESSION['uid']]);
|
||||
|
||||
while ($fline = $f_sth->fetch()) {
|
||||
$is_selected = (in_array($fline["id"], $default_ids)) ? "selected=\"1\"" : "";
|
||||
|
||||
$fline["title"] = " + " . $fline["title"];
|
||||
|
||||
for ($i = 0; $i < $nest_level; $i++)
|
||||
$fline["title"] = " - " . $fline["title"];
|
||||
|
||||
printf("<option $is_selected value='%d'>%s</option>",
|
||||
$fline["id"], htmlspecialchars($fline["title"]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!$root_id) {
|
||||
$is_selected = in_array("CAT:0", $default_ids) ? "selected=\"1\"" : "";
|
||||
|
||||
printf("<option $is_selected value='CAT:0'>%s</option>",
|
||||
__("Uncategorized"));
|
||||
|
||||
$f_sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
|
||||
WHERE cat_id IS NULL AND owner_uid = ? ORDER BY title");
|
||||
$f_sth->execute([$_SESSION['uid']]);
|
||||
|
||||
while ($fline = $f_sth->fetch()) {
|
||||
$is_selected = in_array($fline["id"], $default_ids) ? "selected=\"1\"" : "";
|
||||
|
||||
$fline["title"] = " + " . $fline["title"];
|
||||
|
||||
for ($i = 0; $i < $nest_level; $i++)
|
||||
$fline["title"] = " - " . $fline["title"];
|
||||
|
||||
printf("<option $is_selected value='%d'>%s</option>",
|
||||
$fline["id"], htmlspecialchars($fline["title"]));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$sth = $pdo->prepare("SELECT id,title FROM ttrss_feeds
|
||||
WHERE owner_uid = ? ORDER BY title");
|
||||
$sth->execute([$_SESSION['uid']]);
|
||||
|
||||
while ($line = $sth->fetch()) {
|
||||
|
||||
$is_selected = (in_array($line["id"], $default_ids)) ? "selected=\"1\"" : "";
|
||||
|
||||
printf("<option $is_selected value='%d'>%s</option>",
|
||||
$line["id"], htmlspecialchars($line["title"]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!$root_id) {
|
||||
print "</select>";
|
||||
}
|
||||
}
|
||||
|
||||
function print_feed_cat_select($id, $default_id,
|
||||
$attributes, $include_all_cats = true, $root_id = null, $nest_level = 0) {
|
||||
|
||||
if (!$root_id) {
|
||||
print "<select id=\"$id\" name=\"$id\" default=\"$default_id\" $attributes>";
|
||||
}
|
||||
|
||||
$pdo = DB::pdo();
|
||||
|
||||
if (!$root_id) $root_id = null;
|
||||
|
||||
$sth = $pdo->prepare("SELECT id,title,
|
||||
(SELECT COUNT(id) FROM ttrss_feed_categories AS c2 WHERE
|
||||
c2.parent_cat = ttrss_feed_categories.id) AS num_children
|
||||
FROM ttrss_feed_categories
|
||||
WHERE owner_uid = :uid AND
|
||||
(parent_cat = :root_id OR (:root_id IS NULL AND parent_cat IS NULL)) ORDER BY title");
|
||||
$sth->execute([":uid" => $_SESSION['uid'], ":root_id" => $root_id]);
|
||||
|
||||
$found = 0;
|
||||
|
||||
while ($line = $sth->fetch()) {
|
||||
++$found;
|
||||
|
||||
if ($line["id"] == $default_id) {
|
||||
$is_selected = "selected=\"1\"";
|
||||
} else {
|
||||
$is_selected = "";
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $nest_level; $i++)
|
||||
$line["title"] = " - " . $line["title"];
|
||||
|
||||
if ($line["title"])
|
||||
printf("<option $is_selected value='%d'>%s</option>",
|
||||
$line["id"], htmlspecialchars($line["title"]));
|
||||
|
||||
if ($line["num_children"] > 0)
|
||||
print_feed_cat_select($id, $default_id, $attributes,
|
||||
$include_all_cats, $line["id"], $nest_level+1);
|
||||
}
|
||||
|
||||
if (!$root_id) {
|
||||
if ($include_all_cats) {
|
||||
if ($found > 0) {
|
||||
print "<option disabled=\"1\">--------</option>";
|
||||
}
|
||||
|
||||
if ($default_id == 0) {
|
||||
$is_selected = "selected=\"1\"";
|
||||
} else {
|
||||
$is_selected = "";
|
||||
}
|
||||
|
||||
print "<option $is_selected value=\"0\">".__('Uncategorized')."</option>";
|
||||
}
|
||||
print "</select>";
|
||||
}
|
||||
}
|
||||
|
||||
function stylesheet_tag($filename, $id = false) {
|
||||
$timestamp = filemtime($filename);
|
||||
|
||||
$id_part = $id ? "id=\"$id\"" : "";
|
||||
|
||||
return "<link rel=\"stylesheet\" $id_part type=\"text/css\" href=\"$filename?$timestamp\"/>\n";
|
||||
}
|
||||
|
||||
function javascript_tag($filename) {
|
||||
$query = "";
|
||||
|
||||
if (!(strpos($filename, "?") === FALSE)) {
|
||||
$query = substr($filename, strpos($filename, "?")+1);
|
||||
$filename = substr($filename, 0, strpos($filename, "?"));
|
||||
}
|
||||
|
||||
$timestamp = filemtime($filename);
|
||||
|
||||
if ($query) $timestamp .= "&$query";
|
||||
|
||||
return "<script type=\"text/javascript\" charset=\"utf-8\" src=\"$filename?$timestamp\"></script>\n";
|
||||
}
|
||||
|
||||
function format_warning($msg, $id = "") {
|
||||
return "<div class=\"alert\" id=\"$id\">$msg</div>";
|
||||
}
|
||||
|
||||
function format_notice($msg, $id = "") {
|
||||
return "<div class=\"alert alert-info\" id=\"$id\">$msg</div>";
|
||||
}
|
||||
|
||||
function format_error($msg, $id = "") {
|
||||
return "<div class=\"alert alert-danger\" id=\"$id\">$msg</div>";
|
||||
}
|
||||
|
||||
function print_notice($msg) {
|
||||
return print format_notice($msg);
|
||||
}
|
||||
|
||||
function print_warning($msg) {
|
||||
return print format_warning($msg);
|
||||
}
|
||||
|
||||
function print_error($msg) {
|
||||
return print format_error($msg);
|
||||
}
|
||||
|
||||
function format_inline_player($url, $ctype) {
|
||||
|
||||
$entry = "";
|
||||
|
||||
$url = htmlspecialchars($url);
|
||||
|
||||
if (strpos($ctype, "audio/") === 0) {
|
||||
|
||||
$entry .= "<div class='inline-player'>";
|
||||
|
||||
if ($_SESSION["hasAudio"] && (strpos($ctype, "ogg") !== false ||
|
||||
$_SESSION["hasMp3"])) {
|
||||
|
||||
$entry .= "<audio preload=\"none\" controls>
|
||||
<source type=\"$ctype\" src=\"$url\"/>
|
||||
</audio> ";
|
||||
|
||||
}
|
||||
|
||||
if ($entry) $entry .= "<a target=\"_blank\" rel=\"noopener noreferrer\"
|
||||
href=\"$url\">" . basename($url) . "</a>";
|
||||
|
||||
$entry .= "</div>";
|
||||
|
||||
return $entry;
|
||||
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function print_label_select($name, $value, $attributes = "") {
|
||||
|
||||
$pdo = Db::pdo();
|
||||
|
||||
$sth = $pdo->prepare("SELECT caption FROM ttrss_labels2
|
||||
WHERE owner_uid = ? ORDER BY caption");
|
||||
$sth->execute([$_SESSION['uid']]);
|
||||
|
||||
print "<select default=\"$value\" name=\"" . htmlspecialchars($name) .
|
||||
"\" $attributes>";
|
||||
|
||||
while ($line = $sth->fetch()) {
|
||||
|
||||
$issel = ($line["caption"] == $value) ? "selected=\"1\"" : "";
|
||||
|
||||
print "<option value=\"".htmlspecialchars($line["caption"])."\"
|
||||
$issel>" . htmlspecialchars($line["caption"]) . "</option>";
|
||||
|
||||
}
|
||||
|
||||
# print "<option value=\"ADD_LABEL\">" .__("Add label...") . "</option>";
|
||||
|
||||
print "</select>";
|
||||
|
||||
|
||||
}
|
10
include/db-prefs.php
Normal file
10
include/db-prefs.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
require_once "db.php";
|
||||
|
||||
function get_pref($pref_name, $user_id = false, $die_on_error = false) {
|
||||
return Db_Prefs::get()->read($pref_name, $user_id, $die_on_error);
|
||||
}
|
||||
|
||||
function set_pref($pref_name, $value, $user_id = false, $strip_tags = true) {
|
||||
return Db_Prefs::get()->write($pref_name, $value, $user_id, $strip_tags);
|
||||
}
|
38
include/db.php
Normal file
38
include/db.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
function db_escape_string($s, $strip_tags = true) {
|
||||
return Db::get()->escape_string($s, $strip_tags);
|
||||
}
|
||||
|
||||
function db_query($query, $die_on_error = true) {
|
||||
return Db::get()->query($query, $die_on_error);
|
||||
}
|
||||
|
||||
function db_fetch_assoc($result) {
|
||||
return Db::get()->fetch_assoc($result);
|
||||
}
|
||||
|
||||
|
||||
function db_num_rows($result) {
|
||||
return Db::get()->num_rows($result);
|
||||
}
|
||||
|
||||
function db_fetch_result($result, $row, $param) {
|
||||
return Db::get()->fetch_result($result, $row, $param);
|
||||
}
|
||||
|
||||
function db_affected_rows($result) {
|
||||
return Db::get()->affected_rows($result);
|
||||
}
|
||||
|
||||
function db_last_error() {
|
||||
return Db::get()->last_error();
|
||||
}
|
||||
|
||||
function db_last_query_error() {
|
||||
return Db::get()->last_query_error();
|
||||
}
|
||||
|
||||
function db_quote($str){
|
||||
return Db::get()->quote($str);
|
||||
}
|
74
include/errorhandler.php
Normal file
74
include/errorhandler.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
function format_backtrace($trace) {
|
||||
$rv = "";
|
||||
$idx = 1;
|
||||
|
||||
if (is_array($trace)) {
|
||||
foreach ($trace as $e) {
|
||||
if (isset($e["file"]) && isset($e["line"])) {
|
||||
$fmt_args = [];
|
||||
|
||||
if (is_array($e["args"])) {
|
||||
foreach ($e["args"] as $a) {
|
||||
if (!is_object($a)) {
|
||||
array_push($fmt_args, $a);
|
||||
} else {
|
||||
array_push($fmt_args, "[" . get_class($a) . "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$filename = str_replace(dirname(__DIR__) . "/", "", $e["file"]);
|
||||
|
||||
$rv .= sprintf("%d. %s(%s): %s(%s)\n",
|
||||
$idx, $filename, $e["line"], $e["function"], implode(", ", $fmt_args));
|
||||
|
||||
$idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function ttrss_error_handler($errno, $errstr, $file, $line, $context) {
|
||||
if (error_reporting() == 0 || !$errno) return false;
|
||||
|
||||
$file = substr(str_replace(dirname(dirname(__FILE__)), "", $file), 1);
|
||||
|
||||
$context = format_backtrace(debug_backtrace());
|
||||
$errstr = truncate_middle($errstr, 16384, " (...) ");
|
||||
|
||||
if (class_exists("Logger"))
|
||||
return Logger::get()->log_error($errno, $errstr, $file, $line, $context);
|
||||
}
|
||||
|
||||
function ttrss_fatal_handler() {
|
||||
global $last_query;
|
||||
|
||||
$error = error_get_last();
|
||||
|
||||
if ($error !== NULL) {
|
||||
$errno = $error["type"];
|
||||
$file = $error["file"];
|
||||
$line = $error["line"];
|
||||
$errstr = $error["message"];
|
||||
|
||||
if (!$errno) return false;
|
||||
|
||||
$context = format_backtrace(debug_backtrace());
|
||||
|
||||
$file = substr(str_replace(dirname(dirname(__FILE__)), "", $file), 1);
|
||||
|
||||
if ($last_query) $errstr .= " [Last query: $last_query]";
|
||||
|
||||
if (class_exists("Logger"))
|
||||
return Logger::get()->log_error($errno, $errstr, $file, $line, $context);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
register_shutdown_function('ttrss_fatal_handler');
|
||||
set_error_handler('ttrss_error_handler');
|
||||
|
2554
include/functions.php
Executable file
2554
include/functions.php
Executable file
File diff suppressed because it is too large
Load Diff
156
include/login_form.php
Executable file
156
include/login_form.php
Executable file
@ -0,0 +1,156 @@
|
||||
<?php startup_gettext(); ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Agriget : Login</title>
|
||||
<?php echo stylesheet_tag("css/default.css") ?>
|
||||
<link rel="shortcut icon" type="image/png" href="images/favicon.png">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<?php
|
||||
foreach (array("lib/prototype.js",
|
||||
"lib/dojo/dojo.js",
|
||||
"lib/dojo/tt-rss-layer.js",
|
||||
"js/common.js",
|
||||
"errors.php?mode=js") as $jsfile) {
|
||||
|
||||
echo javascript_tag($jsfile);
|
||||
|
||||
} ?>
|
||||
|
||||
<script type="text/javascript">
|
||||
require({cache:{}});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="flat ttrss_utility ttrss_login">
|
||||
|
||||
<script type="text/javascript">
|
||||
require(['dojo/parser', "dojo/ready", 'dijit/form/Button','dijit/form/CheckBox', 'dijit/form/Form',
|
||||
'dijit/form/Select','dijit/form/TextBox','dijit/form/ValidationTextBox'],function(parser, ready){
|
||||
ready(function() {
|
||||
parser.parse();
|
||||
|
||||
dijit.byId("bw_limit").attr("checked", Cookie.get("ttrss_bwlimit") == 'true');
|
||||
dijit.byId("login").focus();
|
||||
});
|
||||
});
|
||||
|
||||
function fetchProfiles() {
|
||||
xhrJson("public.php", { op: "getprofiles", login: dijit.byId("login").attr('value') },
|
||||
(reply) => {
|
||||
const profile = dijit.byId('profile');
|
||||
|
||||
profile.removeOption(profile.getOptions());
|
||||
|
||||
reply.each((p) => {
|
||||
profile
|
||||
.attr("disabled", false)
|
||||
.addOption(p);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function gotoRegForm() {
|
||||
window.location.href = "register.php";
|
||||
return false;
|
||||
}
|
||||
|
||||
function bwLimitChange(elem) {
|
||||
Cookie.set("ttrss_bwlimit", elem.checked,
|
||||
<?php print SESSION_COOKIE_LIFETIME ?>);
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php $return = urlencode(make_self_url()) ?>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<h1><?php echo "Authentication" ?></h1>
|
||||
<div class="content">
|
||||
<form action="public.php?return=<?php echo $return ?>"
|
||||
dojoType="dijit.form.Form" method="POST">
|
||||
|
||||
<?php print_hidden("op", "login"); ?>
|
||||
|
||||
<?php if ($_SESSION["login_error_msg"]) { ?>
|
||||
<?php echo format_error($_SESSION["login_error_msg"]) ?>
|
||||
<?php $_SESSION["login_error_msg"] = ""; ?>
|
||||
<?php } ?>
|
||||
|
||||
<fieldset>
|
||||
<label><?php echo __("Login:") ?></label>
|
||||
<input name="login" id="login" dojoType="dijit.form.TextBox" type="text"
|
||||
onchange="fetchProfiles()" onfocus="fetchProfiles()" onblur="fetchProfiles()"
|
||||
required="1" value="<?php echo $_SESSION["fake_login"] ?>" />
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<label><?php echo __("Password:") ?></label>
|
||||
|
||||
<input type="password" name="password" required="1"
|
||||
dojoType="dijit.form.TextBox"
|
||||
class="input input-text"
|
||||
value="<?php echo $_SESSION["fake_password"] ?>"/>
|
||||
|
||||
<?php if (strpos(PLUGINS, "auth_internal") !== FALSE) { ?>
|
||||
<a href="public.php?op=forgotpass"><?php echo __("I forgot my password") ?></a>
|
||||
<?php } ?>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<label><?php echo __("Profile:") ?></label>
|
||||
|
||||
<select disabled='disabled' name="profile" id="profile" dojoType='dijit.form.Select'>
|
||||
<option><?php echo __("Default profile") ?></option>
|
||||
</select>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="narrow">
|
||||
<label> </label>
|
||||
|
||||
<label id="bw_limit_label"><input dojoType="dijit.form.CheckBox" name="bw_limit" id="bw_limit"
|
||||
type="checkbox" onchange="bwLimitChange(this)">
|
||||
<?php echo __("Use less traffic") ?></label>
|
||||
</fieldset>
|
||||
|
||||
<div dojoType="dijit.Tooltip" connectId="bw_limit_label" position="below" style="display:none">
|
||||
<?php echo __("Does not display images in articles, reduces automatic refreshes."); ?>
|
||||
</div>
|
||||
|
||||
<?php if (SESSION_COOKIE_LIFETIME > 0) { ?>
|
||||
|
||||
<fieldset class="narrow">
|
||||
<label> </label>
|
||||
<label>
|
||||
<input dojoType="dijit.form.CheckBox" name="remember_me" id="remember_me" type="checkbox">
|
||||
<?php echo __("Remember me") ?>
|
||||
</label>
|
||||
</fieldset>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
<hr/>
|
||||
|
||||
<fieldset class="align-right">
|
||||
<label> </label>
|
||||
|
||||
<button dojoType="dijit.form.Button" type="submit" class="alt-primary"><?php echo __('Log in') ?></button>
|
||||
|
||||
<?php if (defined('ENABLE_REGISTRATION') && ENABLE_REGISTRATION) { ?>
|
||||
<button onclick="return gotoRegForm()" dojoType="dijit.form.Button">
|
||||
<?php echo __("Create new account") ?></button>
|
||||
<?php } ?>
|
||||
</fieldset>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<a href="https://github.com/Fmstrat/agriget/">Agriget</a>
|
||||
© 2005–<?php echo date('Y') ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
248
include/sanity_check.php
Executable file
248
include/sanity_check.php
Executable file
@ -0,0 +1,248 @@
|
||||
<?php
|
||||
/* WARNING!
|
||||
*
|
||||
* If you modify this file, you are ON YOUR OWN!
|
||||
*
|
||||
* Believe it or not, all of the checks below are required to succeed for
|
||||
* tt-rss to actually function properly.
|
||||
*
|
||||
* If you think you have a better idea about what is or isn't required, feel
|
||||
* free to modify the file, note though that you are therefore automatically
|
||||
* disqualified from any further support by official channels, e.g. tt-rss.org
|
||||
* issue tracker or the forums.
|
||||
*
|
||||
* If you come crying when stuff inevitably breaks, you will be mocked and told
|
||||
* to get out. */
|
||||
|
||||
function make_self_url() {
|
||||
$proto = is_server_https() ? 'https' : 'http';
|
||||
|
||||
return $proto . '://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
|
||||
}
|
||||
|
||||
function make_self_url_path() {
|
||||
$proto = is_server_https() ? 'https' : 'http';
|
||||
$url_path = $proto . '://' . $_SERVER["HTTP_HOST"] . parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
|
||||
|
||||
return $url_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
|
||||
*/
|
||||
function initial_sanity_check() {
|
||||
|
||||
$errors = array();
|
||||
|
||||
if (!file_exists("data/config.php")) {
|
||||
array_push($errors, "Configuration file not found. Looks like you forgot to copy config.php-dist to config.php and edit it.");
|
||||
} else {
|
||||
|
||||
require_once "sanity_config.php";
|
||||
|
||||
if (file_exists("install") && !file_exists("data/config.php")) {
|
||||
array_push($errors, "Please copy config.php-dist to config.php or run the installer in install/");
|
||||
}
|
||||
|
||||
if (strpos(PLUGINS, "auth_") === FALSE) {
|
||||
array_push($errors, "Please enable at least one authentication module via PLUGINS constant in config.php");
|
||||
}
|
||||
|
||||
if (function_exists('posix_getuid') && posix_getuid() == 0) {
|
||||
array_push($errors, "Please don't run this script as root.");
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.6.0', '<')) {
|
||||
array_push($errors, "PHP version 5.6.0 or newer required. You're using " . PHP_VERSION . ".");
|
||||
}
|
||||
|
||||
if (CONFIG_VERSION != EXPECTED_CONFIG_VERSION) {
|
||||
array_push($errors, "Configuration file (config.php) has incorrect version. Update it with new options from config.php-dist and set CONFIG_VERSION to the correct value.");
|
||||
}
|
||||
|
||||
if (!is_writable(DATA_DIR)) {
|
||||
array_push($errors, "Data is not writable (chmod -R 777 ".DATA_DIR.")");
|
||||
} else {
|
||||
if (!is_dir(DATA_DIR . "/cache")) mkdir(DATA_DIR . "/cache");
|
||||
if (!is_dir(DATA_DIR . "/lock")) mkdir(DATA_DIR . "/lock");
|
||||
if (!is_dir(DATA_DIR . "/feed-icons")) mkdir(DATA_DIR . "/feed-icons");
|
||||
if (!is_dir(DATA_DIR . "/plugins.local")) mkdir(DATA_DIR . "/plugins.local");
|
||||
if (!is_dir(DATA_DIR . "/themes.local")) mkdir(DATA_DIR . "/themes.local");
|
||||
}
|
||||
|
||||
if (!is_writable(CACHE_DIR)) {
|
||||
array_push($errors, "Cache is not writable (chmod -R 777 ".CACHE_DIR.")");
|
||||
} else {
|
||||
if (!is_dir(CACHE_DIR . "/images")) mkdir(CACHE_DIR . "/images");
|
||||
if (!is_dir(CACHE_DIR . "/upload")) mkdir(CACHE_DIR . "/upload");
|
||||
if (!is_dir(CACHE_DIR . "/export")) mkdir(CACHE_DIR . "/export");
|
||||
if (!is_dir(CACHE_DIR . "/feeds")) mkdir(CACHE_DIR . "/feeds");
|
||||
}
|
||||
|
||||
if (!is_writable(CACHE_DIR . "/images")) {
|
||||
array_push($errors, "Image cache is not writable (chmod -R 777 ".CACHE_DIR."/images)");
|
||||
}
|
||||
|
||||
if (!is_writable(CACHE_DIR . "/upload")) {
|
||||
array_push($errors, "Upload cache is not writable (chmod -R 777 ".CACHE_DIR."/upload)");
|
||||
}
|
||||
|
||||
if (!is_writable(CACHE_DIR . "/export")) {
|
||||
array_push($errors, "Data export cache is not writable (chmod -R 777 ".CACHE_DIR."/export)");
|
||||
}
|
||||
|
||||
if (GENERATED_CONFIG_CHECK != EXPECTED_CONFIG_VERSION) {
|
||||
array_push($errors,
|
||||
"Configuration option checker sanity_config.php is outdated, please recreate it using ./utils/regen_config_checks.sh");
|
||||
}
|
||||
|
||||
foreach ($required_defines as $d) {
|
||||
if (!defined($d)) {
|
||||
array_push($errors,
|
||||
"Required configuration file parameter $d is not defined in config.php. You might need to copy it from config.php-dist.");
|
||||
}
|
||||
}
|
||||
|
||||
if (SINGLE_USER_MODE && class_exists("PDO")) {
|
||||
$pdo = DB::pdo();
|
||||
|
||||
$res = $pdo->query("SELECT id FROM ttrss_users WHERE id = 1");
|
||||
|
||||
if (!$res->fetch()) {
|
||||
array_push($errors, "SINGLE_USER_MODE is enabled in config.php but default admin account is not found.");
|
||||
}
|
||||
}
|
||||
|
||||
$ref_self_url_path = make_self_url_path();
|
||||
$ref_self_url_path = preg_replace("/\w+\.php$/", "", $ref_self_url_path);
|
||||
|
||||
if (SELF_URL_PATH == "http://example.org/tt-rss/") {
|
||||
array_push($errors,
|
||||
"Please set SELF_URL_PATH to the correct value for your server (possible value: <b>$ref_self_url_path</b>)");
|
||||
}
|
||||
|
||||
if (isset($_SERVER["HTTP_HOST"]) &&
|
||||
(!defined('_SKIP_SELF_URL_PATH_CHECKS') || !_SKIP_SELF_URL_PATH_CHECKS) &&
|
||||
SELF_URL_PATH != $ref_self_url_path && SELF_URL_PATH != mb_substr($ref_self_url_path, 0, mb_strlen($ref_self_url_path)-1)) {
|
||||
array_push($errors,
|
||||
"Please set SELF_URL_PATH to the correct value detected for your server: <b>$ref_self_url_path</b>");
|
||||
}
|
||||
|
||||
if (!is_writable(ICONS_DIR)) {
|
||||
array_push($errors, "ICONS_DIR defined in config.php is not writable (chmod -R 777 ".ICONS_DIR.").\n");
|
||||
}
|
||||
|
||||
if (!is_writable(LOCK_DIRECTORY)) {
|
||||
array_push($errors, "LOCK_DIRECTORY defined in config.php is not writable (chmod -R 777 ".LOCK_DIRECTORY.").\n");
|
||||
}
|
||||
|
||||
if (!function_exists("curl_init") && !ini_get("allow_url_fopen")) {
|
||||
array_push($errors, "PHP configuration option allow_url_fopen is disabled, and CURL functions are not present. Either enable allow_url_fopen or install PHP extension for CURL.");
|
||||
}
|
||||
|
||||
if (!function_exists("json_encode")) {
|
||||
array_push($errors, "PHP support for JSON is required, but was not found.");
|
||||
}
|
||||
|
||||
if (DB_TYPE == "mysql" && !function_exists("mysqli_connect")) {
|
||||
array_push($errors, "PHP support for MySQL is required for configured DB_TYPE in config.php.");
|
||||
}
|
||||
|
||||
if (DB_TYPE == "pgsql" && !function_exists("pg_connect")) {
|
||||
array_push($errors, "PHP support for PostgreSQL is required for configured DB_TYPE in config.php");
|
||||
}
|
||||
|
||||
if (!class_exists("PDO")) {
|
||||
array_push($errors, "PHP support for PDO is required but was not found.");
|
||||
}
|
||||
|
||||
if (!function_exists("mb_strlen")) {
|
||||
array_push($errors, "PHP support for mbstring functions is required but was not found.");
|
||||
}
|
||||
|
||||
if (!function_exists("hash")) {
|
||||
array_push($errors, "PHP support for hash() function is required but was not found.");
|
||||
}
|
||||
|
||||
if (ini_get("safe_mode")) {
|
||||
array_push($errors, "PHP safe mode setting is obsolete and not supported by tt-rss.");
|
||||
}
|
||||
|
||||
if (!function_exists("mime_content_type")) {
|
||||
array_push($errors, "PHP function mime_content_type() is missing, try enabling fileinfo module.");
|
||||
}
|
||||
|
||||
if (!class_exists("DOMDocument")) {
|
||||
array_push($errors, "PHP support for DOMDocument is required, but was not found.");
|
||||
}
|
||||
|
||||
if (DB_TYPE == "mysql") {
|
||||
$bad_tables = check_mysql_tables();
|
||||
|
||||
if (count($bad_tables) > 0) {
|
||||
$bad_tables_fmt = [];
|
||||
|
||||
foreach ($bad_tables as $bt) {
|
||||
array_push($bad_tables_fmt, sprintf("%s (%s)", $bt['table_name'], $bt['engine']));
|
||||
}
|
||||
|
||||
$msg = "<p>The following tables use an unsupported MySQL engine: <b>" .
|
||||
implode(", ", $bad_tables_fmt) . "</b>.</p>";
|
||||
|
||||
$msg .= "<p>The only supported engine on MySQL is InnoDB. MyISAM lacks functionality to run
|
||||
tt-rss.
|
||||
Please backup your data (via OPML) and re-import the schema before continuing.</p>
|
||||
<p><b>WARNING: importing the schema would mean LOSS OF ALL YOUR DATA.</b></p>";
|
||||
|
||||
|
||||
array_push($errors, $msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($errors) > 0 && $_SERVER['REQUEST_URI']) { ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Startup failed</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link rel="stylesheet" type="text/css" href="css/default.css">
|
||||
</head>
|
||||
<body class='sanity_failed claro ttrss_utility'>
|
||||
<div class="content">
|
||||
|
||||
<h1>Startup failed</h1>
|
||||
|
||||
<p>Agriget was unable to start properly. This usually means a misconfiguration or an incomplete upgrade. Please fix
|
||||
errors indicated by the following messages:</p>
|
||||
|
||||
<?php foreach ($errors as $error) { echo format_error($error); } ?>
|
||||
|
||||
<p>You might want to check tt-rss <a href="http://tt-rss.org/wiki">wiki</a> or the
|
||||
<a href="http://tt-rss.org/forum">forums</a> for more information. Please search the forums before creating new topic
|
||||
for your question.</p>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php
|
||||
die;
|
||||
} else if (count($errors) > 0) {
|
||||
echo "Agriget was unable to start properly. This usually means a misconfiguration or an incomplete upgrade.\n";
|
||||
echo "Please fix errors indicated by the following messages:\n\n";
|
||||
|
||||
foreach ($errors as $error) {
|
||||
echo " * $error\n";
|
||||
}
|
||||
|
||||
echo "\nYou might want to check tt-rss wiki or the forums for more information.\n";
|
||||
echo "Please search the forums before creating new topic for your question.\n";
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
initial_sanity_check();
|
||||
|
||||
?>
|
3
include/sanity_config.php
Normal file
3
include/sanity_config.php
Normal file
@ -0,0 +1,3 @@
|
||||
<?php # This file has been generated at: Thu Nov 22 22:14:43 MSK 2018
|
||||
define('GENERATED_CONFIG_CHECK', 26);
|
||||
$required_defines = array( 'DB_TYPE', 'DB_HOST', 'DB_USER', 'DB_NAME', 'DB_PASS', 'MYSQL_CHARSET', 'SELF_URL_PATH', 'SINGLE_USER_MODE', 'SIMPLE_UPDATE_MODE', 'PHP_EXECUTABLE', 'LOCK_DIRECTORY', 'CACHE_DIR', 'ICONS_DIR', 'ICONS_URL', 'AUTH_AUTO_CREATE', 'AUTH_AUTO_LOGIN', 'FORCE_ARTICLE_PURGE', 'SPHINX_SERVER', 'SPHINX_INDEX', 'ENABLE_REGISTRATION', 'REG_NOTIFY_ADDRESS', 'REG_MAX_USERS', 'SESSION_COOKIE_LIFETIME', 'SMTP_FROM_NAME', 'SMTP_FROM_ADDRESS', 'DIGEST_SUBJECT', 'CHECK_FOR_UPDATES', 'ENABLE_GZIP_OUTPUT', 'PLUGINS', 'LOG_DESTINATION', 'CONFIG_VERSION'); ?>
|
165
include/sessions.php
Normal file
165
include/sessions.php
Normal file
@ -0,0 +1,165 @@
|
||||
<?php
|
||||
// Original from http://www.daniweb.com/code/snippet43.html
|
||||
|
||||
require_once "data/config.php";
|
||||
require_once "classes/db.php";
|
||||
require_once "autoload.php";
|
||||
require_once "errorhandler.php";
|
||||
require_once "lib/accept-to-gettext.php";
|
||||
require_once "lib/gettext/gettext.inc";
|
||||
require_once "version.php";
|
||||
|
||||
$session_expire = min(2147483647 - time() - 1, max(SESSION_COOKIE_LIFETIME, 86400));
|
||||
$session_name = (!defined('TTRSS_SESSION_NAME')) ? "ttrss_sid" : TTRSS_SESSION_NAME;
|
||||
|
||||
if (is_server_https()) {
|
||||
ini_set("session.cookie_secure", true);
|
||||
}
|
||||
|
||||
ini_set("session.gc_probability", 75);
|
||||
ini_set("session.name", $session_name);
|
||||
ini_set("session.use_only_cookies", true);
|
||||
ini_set("session.gc_maxlifetime", $session_expire);
|
||||
ini_set("session.cookie_lifetime", min(0, SESSION_COOKIE_LIFETIME));
|
||||
|
||||
function session_get_schema_version() {
|
||||
global $schema_version;
|
||||
|
||||
if (!$schema_version) {
|
||||
$row = Db::pdo()->query("SELECT schema_version FROM ttrss_version")->fetch();
|
||||
|
||||
$version = $row["schema_version"];
|
||||
|
||||
$schema_version = $version;
|
||||
return $version;
|
||||
} else {
|
||||
return $schema_version;
|
||||
}
|
||||
}
|
||||
|
||||
function validate_session() {
|
||||
if (SINGLE_USER_MODE) return true;
|
||||
|
||||
if (isset($_SESSION["ref_schema_version"]) && $_SESSION["ref_schema_version"] != session_get_schema_version()) {
|
||||
$_SESSION["login_error_msg"] =
|
||||
__("Session failed to validate (schema version changed)");
|
||||
return false;
|
||||
}
|
||||
$pdo = Db::pdo();
|
||||
|
||||
if ($_SESSION["uid"]) {
|
||||
|
||||
if ($_SESSION["user_agent"] != sha1($_SERVER['HTTP_USER_AGENT'])) {
|
||||
$_SESSION["login_error_msg"] = __("Session failed to validate (UA changed).");
|
||||
return false;
|
||||
}
|
||||
|
||||
$sth = $pdo->prepare("SELECT pwd_hash FROM ttrss_users WHERE id = ?");
|
||||
$sth->execute([$_SESSION['uid']]);
|
||||
|
||||
// user not found
|
||||
if ($row = $sth->fetch()) {
|
||||
$pwd_hash = $row["pwd_hash"];
|
||||
|
||||
if ($pwd_hash != $_SESSION["pwd_hash"]) {
|
||||
|
||||
$_SESSION["login_error_msg"] =
|
||||
__("Session failed to validate (password changed)");
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
||||
$_SESSION["login_error_msg"] =
|
||||
__("Session failed to validate (user not found)");
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
function ttrss_open ($s, $n) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function ttrss_read ($id){
|
||||
global $session_expire;
|
||||
|
||||
$sth = Db::pdo()->prepare("SELECT data FROM ttrss_sessions WHERE id=?");
|
||||
$sth->execute([$id]);
|
||||
|
||||
if ($row = $sth->fetch()) {
|
||||
return base64_decode($row["data"]);
|
||||
|
||||
} else {
|
||||
$expire = time() + $session_expire;
|
||||
|
||||
$sth = Db::pdo()->prepare("INSERT INTO ttrss_sessions (id, data, expire)
|
||||
VALUES (?, '', ?)");
|
||||
$sth->execute([$id, $expire]);
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function ttrss_write ($id, $data) {
|
||||
global $session_expire;
|
||||
|
||||
$data = base64_encode($data);
|
||||
$expire = time() + $session_expire;
|
||||
|
||||
$sth = Db::pdo()->prepare("SELECT id FROM ttrss_sessions WHERE id=?");
|
||||
$sth->execute([$id]);
|
||||
|
||||
if ($row = $sth->fetch()) {
|
||||
$sth = Db::pdo()->prepare("UPDATE ttrss_sessions SET data=?, expire=? WHERE id=?");
|
||||
$sth->execute([$data, $expire, $id]);
|
||||
} else {
|
||||
$sth = Db::pdo()->prepare("INSERT INTO ttrss_sessions (id, data, expire)
|
||||
VALUES (?, ?, ?)");
|
||||
$sth->execute([$id, $data, $expire]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function ttrss_close () {
|
||||
return true;
|
||||
}
|
||||
|
||||
function ttrss_destroy($id) {
|
||||
$sth = Db::pdo()->prepare("DELETE FROM ttrss_sessions WHERE id = ?");
|
||||
$sth->execute([$id]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*/
|
||||
function ttrss_gc ($expire) {
|
||||
Db::pdo()->query("DELETE FROM ttrss_sessions WHERE expire < " . time());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!SINGLE_USER_MODE /* && DB_TYPE == "pgsql" */) {
|
||||
session_set_save_handler("ttrss_open",
|
||||
"ttrss_close", "ttrss_read", "ttrss_write",
|
||||
"ttrss_destroy", "ttrss_gc");
|
||||
register_shutdown_function('session_write_close');
|
||||
}
|
||||
|
||||
if (!defined('NO_SESSION_AUTOSTART')) {
|
||||
if (isset($_COOKIE[session_name()])) {
|
||||
@session_start();
|
||||
}
|
||||
}
|
43
include/version.php
Normal file
43
include/version.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
define('VERSION_STATIC', '19.2');
|
||||
|
||||
function get_version() {
|
||||
date_default_timezone_set('UTC');
|
||||
$root_dir = dirname(dirname(__FILE__));
|
||||
|
||||
if (is_dir("$root_dir/.git") && file_exists("$root_dir/.git/HEAD")) {
|
||||
$head = trim(file_get_contents("$root_dir/.git/HEAD"));
|
||||
|
||||
if ($head) {
|
||||
$matches = array();
|
||||
|
||||
if (preg_match("/^ref: (.*)/", $head, $matches)) {
|
||||
$ref = $matches[1];
|
||||
|
||||
if (!file_exists("$root_dir/.git/$ref"))
|
||||
return VERSION_STATIC;
|
||||
$suffix = substr(trim(file_get_contents("$root_dir/.git/$ref")), 0, 7);
|
||||
$timestamp = filemtime("$root_dir/.git/$ref");
|
||||
|
||||
define("GIT_VERSION_HEAD", $suffix);
|
||||
define("GIT_VERSION_TIMESTAMP", $timestamp);
|
||||
|
||||
return VERSION_STATIC . " ($suffix)";
|
||||
|
||||
} else {
|
||||
$suffix = substr(trim($head), 0, 7);
|
||||
$timestamp = filemtime("$root_dir/.git/HEAD");
|
||||
|
||||
define("GIT_VERSION_HEAD", $suffix);
|
||||
define("GIT_VERSION_TIMESTAMP", $timestamp);
|
||||
|
||||
return VERSION_STATIC . " ($suffix)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VERSION_STATIC;
|
||||
|
||||
}
|
||||
|
||||
define('VERSION', get_version());
|
Reference in New Issue
Block a user