pull/10/head 1.0.3
Rodolfo Berrios 2016-10-12 13:32:18 -03:00
parent 2c3d758ac9
commit 521be5152d
40 changed files with 608 additions and 442 deletions

View File

@ -1,5 +1,5 @@
<?php
define('G_APP_NAME', 'Chevereto Free');
define('G_APP_VERSION', '1.0.2');
define('G_APP_VERSION', '1.0.3');
define('G_APP_GITHUB_OWNER', 'Chevereto');
define('G_APP_GITHUB_REPO', 'Chevereto-Free');

View File

@ -1,9 +1,11 @@
html, body {
height: 100%;
margin: 0;
padding: 0;
background: #F4F4F4;
}
body {
background: #F4F4F4;
color: #333;
}
@ -58,7 +60,7 @@ ul.errors {
color: #BBB;
text-shadow: 0 1px 0 #FFF;
text-align: center;
margin: 10px;
padding: 10px;
}
#powered a {
color: #BBB;

View File

@ -208,6 +208,11 @@ try {
],
'1.0.1' => NULL,
'1.0.2' => NULL,
'1.0.3' => [
'upload_enabled_image_formats' => 'jpg,png,bmp,gif',
'upload_threads' => '2',
'enable_automatic_updates_check'=> 1,
]
];
// Settings that must be renamed from NAME to NEW NAME and DELETE old NAME
@ -629,6 +634,7 @@ UPDATE `%table_prefix%users` SET user_content_views = COALESCE((SELECT SUM(image
foreach($db_details as $k => $v) {
$settings_php[] = '$settings[\'db_'.$k.'\'] = \''.$v.'\';';
}
$settings_php[] = '$settings[\'db_pdo_attrs\'] = [];';
$settings_php[] = '$settings[\'debug_level\'] = 1;';
$settings_php = implode("\n", $settings_php);
$settings_file = G_APP_PATH . 'settings.php';
@ -735,7 +741,7 @@ UPDATE `%table_prefix%users` SET user_content_views = COALESCE((SELECT SUM(image
ADD `image_thumb_size` int(11) NOT NULL,
ADD `image_medium_size` int(11) NOT NULL DEFAULT '0',
ADD `image_expiration_date_gmt` datetime DEFAULT NULL,
ADD `image_likes` bigint(32) NOT NULL DEFAULT '0',
ADD `image_is_animated` tinyint(1) NOT NULL DEFAULT '0',
ADD INDEX `image_name` (`image_name`),
ADD INDEX `image_size` (`image_size`),
ADD INDEX `image_width` (`image_width`),
@ -750,6 +756,7 @@ UPDATE `%table_prefix%users` SET user_content_views = COALESCE((SELECT SUM(image
ADD INDEX `image_views` (`image_views`),
ADD INDEX `image_category_id` (`image_category_id`),
ADD INDEX `image_expiration_date_gmt` (`image_expiration_date_gmt`),
ADD INDEX `image_is_animated` (`image_is_animated`),
ENGINE=".$fulltext_engine.";
UPDATE `chv_images`

View File

@ -104,15 +104,15 @@ $(function(){
});
// Close upload box
$("[data-action=close-upload], [data-action=cancel-upload]", $anywhere_upload).click(function() {
$("[data-action=close-upload]", $anywhere_upload).click(function() {
if($anywhere_upload.is(":animated")) return;
$("[data-action=top-bar-upload]", "#top-bar").click();
});
// Cancel remaining uploads
$("[data-action=cancel-upload-remaining]", $anywhere_upload).click(function() {
$("[data-action=cancel-upload-remaining], [data-action=cancel-upload]", $anywhere_upload).click(function() {
$("[data-action=cancel]", $anywhere_upload_queue).click();
CHV.fn.uploader.is_uploading = false;
CHV.fn.uploader.isUploading = false;
if(CHV.fn.uploader.results.success.length > 0) {
CHV.fn.uploader.displayResults();
return;
@ -413,7 +413,7 @@ $(function(){
$("[data-group=uploading]", $anywhere_upload).show();
CHV.fn.uploader.queueSize();
CHV.fn.uploader.can_add = false;
CHV.fn.uploader.canAdd = false;
$queue_items = $("li", $anywhere_upload_queue);
$queue_items.addClass("uploading waiting");
@ -1876,7 +1876,7 @@ CHV.fn.bindSelectableItems = function() {
}
$("#content-listing-wrapper").selectable({
filter: PF.obj.listing.selectors.list_item,
cancel: ".content-empty, .header, #tab-share, #tab-full-info, .viewer-title, .header-link, .top-bar, .content-listing-pagination *, #fullscreen-modal, #top-user, #background-cover, .list-item-desc, .list-item-image-tools, [data-action=load-image]",
cancel: ".content-empty, .header, #tab-share, #tab-full-info, .viewer-title, .header-link, .top-bar, .content-listing-pagination *, #fullscreen-modal, #top-user, #background-cover, .list-item-desc, .list-item-image-tools, [data-action=load-image], #tab-codes",
delay: 5, // Avoids unattended click reset
selecting: function(event, ui) {
var $this = $(ui.selecting);
@ -1989,11 +1989,6 @@ CHV.obj.topBar = {
CHV.fn.uploader = {
options: {
image_types: ["png", "jpg", "jpeg", "gif", "bmp"],
max_filesize: "2 MB"
},
selectors: {
root: "#anywhere-upload",
queue: "#anywhere-upload-queue",
@ -2011,9 +2006,9 @@ CHV.fn.uploader = {
paste: "#anywhere-upload-paste",
},
is_uploading: false,
can_add: true,
queue_status : "ready",
isUploading: false,
canAdd: true,
queueStatus : "ready",
files: {},
results: {success: [], error: []},
@ -2030,7 +2025,7 @@ CHV.fn.uploader = {
PF.fn.growl.close(true);
PF.fn.close_pops();
if(this.toggleWorking == 1 || $(CHV.fn.uploader.selectors.root).is(":animated") || CHV.fn.uploader.is_uploading || ($switch.data('login-needed') && !PF.fn.is_user_logged())) return;
if(this.toggleWorking == 1 || $(CHV.fn.uploader.selectors.root).is(":animated") || CHV.fn.uploader.isUploading || ($switch.data('login-needed') && !PF.fn.is_user_logged())) return;
this.toggleWorking = 1;
@ -2182,10 +2177,10 @@ CHV.fn.uploader = {
reset: function() {
this.files = {};
this.is_uploading = false;
this.can_add = true;
this.isUploading = false;
this.canAdd = true;
this.results = {success: [], error: []};
this.queue_status = "ready";
this.queueStatus = "ready";
$("li", this.selectors.queue).remove();
$(this.selectors.anywhere).height("").css({"overflow-y": "", "overflow-x": ""});
@ -2310,18 +2305,14 @@ CHV.fn.uploader = {
}
},
item_add_id : 0,
filesAddId : 0,
clipboardImages : [],
add: function(e, urls) {
var md5;
if(typeof CHV.obj.config !== "undefined" && typeof CHV.obj.config.image !== "undefined" && CHV.obj.config.image.max_filesize !== "undefined") {
this.options.max_filesize = CHV.obj.config.image.max_filesize;
}
// Prevent add items ?
if(!this.can_add) {
if(!this.canAdd) {
var e = e.originalEvent;
e.preventDefault();
e.stopPropagation();
@ -2365,8 +2356,8 @@ CHV.fn.uploader = {
failed_files.push({uid: i, name: file.name.truncate_middle() + " - " + PF.fn._s("File too big.")});
continue;
}
// Android can output shit like image:10 as the full file name so ignore this filter
if(CHV.fn.uploader.options.image_types.indexOf(image_type_str) == -1 && /android/i.test(navigator.userAgent) == false) {
// Android can output something like image:10 as the full file name so ignore this filter
if(CHV.obj.config.upload.image_types.indexOf(image_type_str) == -1 && /android/i.test(navigator.userAgent) == false) {
failed_files.push({uid: i, name: file.name.truncate_middle() + " - " + PF.fn._s("Invalid or unsupported file format.")});
continue;
}
@ -2396,6 +2387,8 @@ CHV.fn.uploader = {
return;
}
} else { // Remote files
// Strip HTML + BBCode
urls = urls.replace(/(<([^>]+)>)/g, '').replace(/(\[([^\]]+)\])/g, '');
files = urls.match_urls();
if(!files) return;
files = files.array_unique();
@ -2408,7 +2401,7 @@ CHV.fn.uploader = {
if($.isEmptyObject(this.files)) {
for(var i=0; i<files.length; i++) {
this.files[files[i].uid] = files[i];
this.item_add_id++;
this.filesAddId++;
}
} else {
/**
@ -2425,8 +2418,8 @@ CHV.fn.uploader = {
if($.inArray(encodeURI(file.name), currentfiles) != -1) {
return null;
}
file.uid = CHV.fn.uploader.item_add_id + i;
CHV.fn.uploader.item_add_id++;
file.uid = CHV.fn.uploader.filesAddId + i;
CHV.fn.uploader.filesAddId++;
return file;
});
for(var i = 0; i < files.length; i++){
@ -2448,7 +2441,7 @@ CHV.fn.uploader = {
j = 0,
default_options = {
canvas: true,
//maxWidth: 600
maxWidth: 600
};
function CHVLoadImage(i) {
@ -2517,7 +2510,6 @@ CHV.fn.uploader = {
title: title,
width: img.width,
height: img.height,
canvas: img, // store source canvas (for client side resizing) - huge memory leak
mimetype: mimetype,
};
@ -2611,19 +2603,39 @@ CHV.fn.uploader = {
$("[data-text=queue-size]", this.selectors.root).text(Object.size(this.files));
},
queueProgress: function(e) {
var total_queue_items_done = $("> .completed, > .failed", this.selectors.queue).length,
total_queue_items = $(this.selectors.queue).children().length,
total_queueProgress = parseInt(100 * (parseFloat(total_queue_items_done/total_queue_items) + parseFloat((e.loaded / e.total)/total_queue_items)));
$("[data-text=queue-progress]", this.selectors.root).text(total_queueProgress);
queueProgress: function(e, id) {
var queue_size = Object.keys(this.files).length;
this.files[id].progress = e.loaded / e.total;
var progress = 0;
for(var i=0; i < queue_size; i++) {
if(typeof this.files[i] == typeof undefined || !('progress' in this.files[i])) continue;
progress += this.files[i].progress;
}
$("[data-text=queue-progress]", this.selectors.root).text(parseInt(100 * progress / queue_size));
},
uploadThreads: 0,
uploadParsedIds: [],
upload: function($queue_item) {
var id = $queue_item.data("id"),
f = this.files[id],
queue_is_url = typeof f.url !== "undefined";
var id = $queue_item.data("id");
var nextId = $queue_item.next().exists() ? $queue_item.next().data("id") : false;
// Already working on this?
if($.inArray(id, this.uploadParsedIds) !== -1) {
if($queue_item.next().exists()) {
this.upload($queue_item.next());
}
return;
}
var self = this;
this.uploadParsedIds.push(id);
var f = this.files[id];
var queue_is_url = typeof f.url !== "undefined";
var source = queue_is_url ? f.url : f;
var hasForm = typeof f.formValues !== typeof undefined;
@ -2638,18 +2650,13 @@ CHV.fn.uploader = {
if($(this).data("action") == "cancel-upload") $(this).show();
});
this.is_uploading = true;
this.uploadThreads += 1;
// Client side resizing
if(!queue_is_url && f.parsedMeta.mimetype !== "image/gif" && typeof f.formValues !== typeof undefined && f.formValues.width != f.parsedMeta.width) {
isBlob = true;
var canvas = $("<canvas />")[0];
canvas.width = f.formValues.width;
canvas.height = f.formValues.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(f.parsedMeta.canvas, 0, 0, canvas.width, canvas.height);
source = PF.fn.dataURItoBlob(canvas.toDataURL(f.parsedMeta.mimetype));
};
if(this.uploadThreads < CHV.obj.config.upload.threads && nextId !== false) {
this.upload($queue_item.next());
}
this.isUploading = true;
// HTML5 form
var form = new FormData();
@ -2688,7 +2695,7 @@ CHV.fn.uploader = {
if(e.lengthComputable) {
CHV.fn.uploader.queueProgress(e);
CHV.fn.uploader.queueProgress(e, id);
percentComplete = parseInt((e.loaded / e.total) * 100);
@ -2704,7 +2711,7 @@ CHV.fn.uploader = {
}
} else {
this.queueSize();
this.queueProgress({loaded: 1, total: 1});
this.queueProgress({loaded: 1, total: 1}, id);
this.itemLoading($queue_item);
}
@ -2714,6 +2721,8 @@ CHV.fn.uploader = {
if(this.readyState == 4 && typeof CHV.fn.uploader.files[id].xhr !== "undefined" && CHV.fn.uploader.files[id].xhr.status !== 0) {
self.uploadThreads -= 1;
$(".loading-indicator", $queue_item).remove();
$queue_item.removeClass("waiting uploading");
@ -2776,13 +2785,15 @@ CHV.fn.uploader = {
PF.fn.bindtipTip($queue_item);
}
if($queue_item.next().exists()) {
if(self.uploadThreads < CHV.obj.config.upload.threads && nextId !== false) {
CHV.fn.uploader.upload($queue_item.next());
$(CHV.fn.uploader.selectors.close_cancel, CHV.fn.uploader.selectors.root).hide().each(function() {
if($(this).data("action") == "cancel-upload-remaining") $(this).show();
if($(this).data("action") == "cancel-upload-remaining") {
$(this).show();
}
});
} else {
CHV.fn.uploader.is_uploading = false;
CHV.fn.uploader.isUploading = false;
CHV.fn.uploader.displayResults();
}
$(".done", $queue_item).fadeOut();
@ -2859,7 +2870,7 @@ CHV.fn.uploader = {
}
this.boxSizer();
this.queue_status = "done";
this.queueStatus = "done";
}

View File

@ -4,7 +4,7 @@ function showHomeCover(){$("body").addClass("load");if(!$("#maintenance-wrapper"
setTimeout(function(){$("body").addClass("loaded");setTimeout(function(){showHomeSlideshow();},7000);},400*1.5);}
var showHomeSlideshowInterval=function(){setTimeout(function(){showHomeSlideshow();},8000);};function showHomeSlideshow(){var $image=$(".home-cover-img[data-src]","#home-cover-slideshow").first();var $images=$(".home-cover-img","#home-cover-slideshow");if($image.length==0){if($images.length==1)return;$images.first().removeClass("animate-in");$("#home-cover-slideshow").append($images.first());setTimeout(function(){$(".home-cover-img:last","#home-cover-slideshow").addClass("animate-in");},20);setTimeout(function(){$(".home-cover-img:not(:last)","#home-cover-slideshow").removeClass("animate-in");},4000);showHomeSlideshowInterval();}else{var src=$image.attr("data-src");$("<img/>").attr("src",src).on("load error",function(){$(this).remove();$image.css("background-image","url("+src+")").addClass("animate-in").removeAttr("data-src");setTimeout(function(){$(".home-cover-img:not(:last)","#home-cover-slideshow").removeClass("animate-end animate-in--alt");},2000);showHomeSlideshowInterval();});}}
if(landing_src){$("<img/>").attr("src",landing_src).on("load error",function(){$(this).remove();showHomeCover();});}else{showHomeCover();}}
var anywhere_upload=CHV.fn.uploader.selectors.root,anywhere_upload_queue=CHV.fn.uploader.selectors.queue,$anywhere_upload=$(anywhere_upload),$anywhere_upload_queue=$(anywhere_upload_queue);$(document).on("click","[data-action=top-bar-upload]",function(e){CHV.fn.uploader.toggle();});$("[data-action=close-upload], [data-action=cancel-upload]",$anywhere_upload).click(function(){if($anywhere_upload.is(":animated"))return;$("[data-action=top-bar-upload]","#top-bar").click();});$("[data-action=cancel-upload-remaining]",$anywhere_upload).click(function(){$("[data-action=cancel]",$anywhere_upload_queue).click();CHV.fn.uploader.is_uploading=false;if(CHV.fn.uploader.results.success.length>0){CHV.fn.uploader.displayResults();return;}else{CHV.fn.uploader.reset();}});$(document).on("click","[data-action=upload-privacy]:not(disabled)",function(e){if(e.isDefaultPrevented())return;current_privacy=$(this).data("privacy");target_privacy=current_privacy=="public"?"private":"public";this_lock=$(".icon",this).data("lock");this_unlock=$(".icon",this).data("unlock");$(".icon",this).removeClass(this_lock+" "+this_unlock).addClass(current_privacy=="public"?this_lock:this_unlock);$(this).data("privacy",target_privacy);$("[data-action=upload-privacy-copy]").html($("[data-action=upload-privacy]").html());$upload_button=$("[data-action=upload]",$anywhere_upload);$upload_button.text($upload_button.data(target_privacy));$(this).tipTip("hide");});$(CHV.fn.uploader.selectors.file+", "+CHV.fn.uploader.selectors.camera).on("change",function(e){if(!$(CHV.fn.uploader.selectors.root).data("shown")){CHV.fn.uploader.toggle({callback:function(e){CHV.fn.uploader.add(e);}},e);}else{CHV.fn.uploader.add(e);}}).on("click",function(e){if($(this).data('login-needed')&&!PF.fn.is_user_logged()){return;}});function isFileTransfer(e){var e=e.originalEvent,isFileTransfer=false;if(e.dataTransfer.types){for(var i=0;i<e.dataTransfer.types.length;i++){if(e.dataTransfer.types[i]=="Files"){isFileTransfer=true;break;}}}
var anywhere_upload=CHV.fn.uploader.selectors.root,anywhere_upload_queue=CHV.fn.uploader.selectors.queue,$anywhere_upload=$(anywhere_upload),$anywhere_upload_queue=$(anywhere_upload_queue);$(document).on("click","[data-action=top-bar-upload]",function(e){CHV.fn.uploader.toggle();});$("[data-action=close-upload]",$anywhere_upload).click(function(){if($anywhere_upload.is(":animated"))return;$("[data-action=top-bar-upload]","#top-bar").click();});$("[data-action=cancel-upload-remaining], [data-action=cancel-upload]",$anywhere_upload).click(function(){$("[data-action=cancel]",$anywhere_upload_queue).click();CHV.fn.uploader.isUploading=false;if(CHV.fn.uploader.results.success.length>0){CHV.fn.uploader.displayResults();return;}else{CHV.fn.uploader.reset();}});$(document).on("click","[data-action=upload-privacy]:not(disabled)",function(e){if(e.isDefaultPrevented())return;current_privacy=$(this).data("privacy");target_privacy=current_privacy=="public"?"private":"public";this_lock=$(".icon",this).data("lock");this_unlock=$(".icon",this).data("unlock");$(".icon",this).removeClass(this_lock+" "+this_unlock).addClass(current_privacy=="public"?this_lock:this_unlock);$(this).data("privacy",target_privacy);$("[data-action=upload-privacy-copy]").html($("[data-action=upload-privacy]").html());$upload_button=$("[data-action=upload]",$anywhere_upload);$upload_button.text($upload_button.data(target_privacy));$(this).tipTip("hide");});$(CHV.fn.uploader.selectors.file+", "+CHV.fn.uploader.selectors.camera).on("change",function(e){if(!$(CHV.fn.uploader.selectors.root).data("shown")){CHV.fn.uploader.toggle({callback:function(e){CHV.fn.uploader.add(e);}},e);}else{CHV.fn.uploader.add(e);}}).on("click",function(e){if($(this).data('login-needed')&&!PF.fn.is_user_logged()){return;}});function isFileTransfer(e){var e=e.originalEvent,isFileTransfer=false;if(e.dataTransfer.types){for(var i=0;i<e.dataTransfer.types.length;i++){if(e.dataTransfer.types[i]=="Files"){isFileTransfer=true;break;}}}
return isFileTransfer;}
if($(CHV.fn.uploader.selectors.root).exists()){$("body").on({dragenter:function(e){e.preventDefault();if(!isFileTransfer(e)){return false;}
if(!$(CHV.fn.uploader.selectors.dropzone).exists()){$("body").append($('<div id="'+CHV.fn.uploader.selectors.dropzone.replace("#","")+'"/>').css({width:"100%",height:"100%",position:"fixed",zIndex:1000,left:0,top:0}));}}});$(document).on({dragover:function(e){e.preventDefault();if(!isFileTransfer(e)){return false;}
@ -23,7 +23,7 @@ $("#tiptip_holder").hide();$item.tipTip("destroy").remove();if(queue_height!==$q
if(!$("li",$anywhere_upload_queue).exists()){$("[data-group=upload-queue-ready], [data-group=upload-queue], [data-group=upload-queue-ready]",$anywhere_upload).css("display","");}
if(CHV.fn.uploader.files[id]&&typeof CHV.fn.uploader.files[id].xhr!=="undefined"){CHV.fn.uploader.files[id].xhr.abort();item_xhr_cancel=true;}
if(typeof CHV.fn.uploader.files[id]!==typeof undefined&&typeof CHV.fn.uploader.files[id].fromClipboard!==typeof undefined){var c_md5=CHV.fn.uploader.files[id].md5;var c_index=CHV.fn.uploader.clipboardImages.indexOf(c_md5);if(c_index>-1){CHV.fn.uploader.clipboardImages.splice(c_index,1);}}
delete CHV.fn.uploader.files[id];CHV.fn.uploader.queueSize();if(Object.size(CHV.fn.uploader.files)==0){if(CHV.fn.uploader.results.success.length==0&&CHV.fn.uploader.results.error.length==0){CHV.fn.uploader.reset();}}else{if(item_xhr_cancel){if($("li.waiting",$queue).first().length!==0){CHV.fn.uploader.upload($("li.waiting",$queue).first());}else if(CHV.fn.uploader.results.success.length!==0||CHV.fn.uploader.results.error.length!==0){CHV.fn.uploader.displayResults();}}}});$(document).on("click","[data-action=upload]",function(){$("[data-group=upload], [data-group=upload-queue-ready]",$anywhere_upload).hide();$("[data-group=uploading]",$anywhere_upload).show();CHV.fn.uploader.queueSize();CHV.fn.uploader.can_add=false;$queue_items=$("li",$anywhere_upload_queue);$queue_items.addClass("uploading waiting");CHV.fn.uploader.timestamp=new Date().getTime();CHV.fn.uploader.upload($queue_items.first("li"));});if($("body#user").exists()){if(PF.obj.listing.query_string.page>1){var State=History.getState();console.log(State.data)
delete CHV.fn.uploader.files[id];CHV.fn.uploader.queueSize();if(Object.size(CHV.fn.uploader.files)==0){if(CHV.fn.uploader.results.success.length==0&&CHV.fn.uploader.results.error.length==0){CHV.fn.uploader.reset();}}else{if(item_xhr_cancel){if($("li.waiting",$queue).first().length!==0){CHV.fn.uploader.upload($("li.waiting",$queue).first());}else if(CHV.fn.uploader.results.success.length!==0||CHV.fn.uploader.results.error.length!==0){CHV.fn.uploader.displayResults();}}}});$(document).on("click","[data-action=upload]",function(){$("[data-group=upload], [data-group=upload-queue-ready]",$anywhere_upload).hide();$("[data-group=uploading]",$anywhere_upload).show();CHV.fn.uploader.queueSize();CHV.fn.uploader.canAdd=false;$queue_items=$("li",$anywhere_upload_queue);$queue_items.addClass("uploading waiting");CHV.fn.uploader.timestamp=new Date().getTime();CHV.fn.uploader.upload($queue_items.first("li"));});if($("body#user").exists()){if(PF.obj.listing.query_string.page>1){var State=History.getState();console.log(State.data)
if(State.data&&typeof State.data.scrollTop!=="undefined"){if($(window).scrollTop()!==State.data.scrollTop){$(window).scrollTop(State.data.scrollTop);}}else{var scrollTop=$("#background-cover").height()-160;$("html, body").animate({scrollTop:scrollTop},0);}}}
if(!PF.fn.isDevice('phone')){if($("#top-bar-shade").exists()){if($("#top-bar-shade").css("opacity")){$("#top-bar-shade").data("initial-opacity",Number($("#top-bar-shade").css("opacity")));}}
$(window).scroll(function(){var Y=$(window).scrollTop();var is_slim_shady=$("#top-bar-shade").exists()&&!$("html").hasClass("top-bar-box-shadow-none");if(Y<0)return;var $top_bar=$("#top-bar");var rate=Number(Y /($("#background-cover, [data-content=follow-scroll-opacity]").height()-$top_bar.height()));if(rate>1)rate=1;if(is_slim_shady){if($("#top-bar-shade").data("initial-opacity")){rate+=$("#top-bar-shade").data("initial-opacity");}
@ -97,8 +97,8 @@ $this.addClass("list-item-play-gif--loading");var $parent=$this.closest(".list-i
var $image=$("img",$imageContainer);var md=".md";var imageSrc=$image.attr("src");var mdIndex=imageSrc.lastIndexOf(md);var loadSrc=imageSrc.substr(0,mdIndex)+imageSrc.substr(mdIndex+md.length,imageSrc.length);$imageContainer.append($imageContainer.html());$load=$parent.find(".image-container img").eq(1).attr("src",loadSrc).addClass("hidden");$load.imagesLoaded(function(){$this.remove();$image.remove();$(this.elements).removeClass("hidden");});}});if(typeof CHV=="undefined"){CHV={obj:{},fn:{},str:{}};}
CHV.obj.image_viewer={selector:"#image-viewer",container:"#image-viewer-container",navigation:".image-viewer-navigation",loading:"#image-viewer-loading",loader:"#image-viewer-loader",};CHV.obj.image_viewer.$container=$(CHV.obj.image_viewer.container);CHV.obj.image_viewer.$navigation=$(CHV.obj.image_viewer.navigation);CHV.obj.image_viewer.$loading=$(CHV.obj.image_viewer.loading);CHV.fn.system={checkUpdates:function(callback){$.ajax({url:"https://chevereto.com/api/get/info/free/",data:null,cache:false}).always(function(data,status,XHR){if(typeof callback=="function"){callback(XHR);}});}};CHV.fn.bindSelectableItems=function(){var el='content-listing-wrapper';if(!$("#"+el).exists()){$("[data-content=list-selection]").closest(".content-width").wrap("<div id='"+el+"' />");}
if(!$("[data-content=list-selection]").exists()||PF.fn.isDevice(["phone","phablet"])){return;}
$("#content-listing-wrapper").selectable({filter:PF.obj.listing.selectors.list_item,cancel:".content-empty, .header, #tab-share, #tab-full-info, .viewer-title, .header-link, .top-bar, .content-listing-pagination *, #fullscreen-modal, #top-user, #background-cover, .list-item-desc, .list-item-image-tools, [data-action=load-image]",delay:5,selecting:function(event,ui){var $this=$(ui.selecting);var unselect=$this.hasClass("selected");CHV.fn.list_editor[(unselect?"unselect":"select")+"Item"]($this);},unselecting:function(event,ui){CHV.fn.list_editor.unselectItem($(ui.unselecting));}});};CHV.fn.isCachedImage=function(src){var image=new Image();image.src=src;return image.complete||image.width+image.height>0;};CHV.fn.viewerImageZoomClass=function(){if(CHV.obj.image_viewer.$container.hasClass("jscursor-zoom-in")){CHV.obj.image_viewer.$container.addClass("cursor-zoom-in").removeClass("jscursor-zoom-in");}};CHV.fn.viewerLoadImage=function(){if(CHV.obj.image_viewer.$loading.exists()){CHV.obj.image_viewer.$loading.removeClass("soft-hidden").css({zIndex:2});PF.fn.loading.inline(CHV.obj.image_viewer.$loading,{color:"white",size:"small",center:true,valign:true});CHV.obj.image_viewer.$loading.hide().fadeIn("slow");}
$(CHV.obj.image_viewer.loader).remove();CHV.obj.image_viewer.image.html=CHV.obj.image_viewer.$container.html();CHV.obj.image_viewer.$container.prepend($(CHV.obj.image_viewer.image.html).css({top:0,zIndex:0}));CHV.obj.image_viewer.$container.find("img").eq(0).css("zIndex",1);CHV.obj.image_viewer.$container.find("img").eq(1).attr("src",CHV.obj.image_viewer.image.url).css({width:"100%",height:"auto"});CHV.obj.image_viewer.$container.find("img").eq(1).imagesLoaded(function(){CHV.obj.image_viewer.$container.find("img").eq(1).css({width:"",height:""});CHV.obj.image_viewer.$container.find("img").eq(0).remove();PF.fn.loading.destroy(CHV.obj.image_viewer.$loading);});};CHV.obj.embed_tpl={};CHV.obj.topBar={transparencyScrollToggle:function(){var Y=$(window).scrollTop();$("#top-bar")[(Y>0?"remove":"add")+"Class"]("transparent");}};CHV.fn.uploader={options:{image_types:["png","jpg","jpeg","gif","bmp"],max_filesize:"2 MB"},selectors:{root:"#anywhere-upload",queue:"#anywhere-upload-queue",queue_complete:".queue-complete",queue_item:".queue-item",close_cancel:"[data-button=close-cancel]",file:"#anywhere-upload-input",camera:"#anywhere-upload-input-camera",upload_item_template:"#anywhere-upload-item-template",item_progress_bar:"[data-content=progress-bar]",item_progress_percent:"[data-text=progress-percent]",failed_result:"[data-content=failed-upload-result]",fullscreen_mask:"#fullscreen-uploader-mask",dropzone:"#uploader-dropzone",paste:"#anywhere-upload-paste",},is_uploading:false,can_add:true,queue_status:"ready",files:{},results:{success:[],error:[]},toggleWorking:0,toggle:function(options,args){var $switch=$("[data-action=top-bar-upload]",".top-bar");var show=!$(CHV.fn.uploader.selectors.root).data("shown");var options=$.extend({callback:null,reset:true},options);PF.fn.growl.close(true);PF.fn.close_pops();if(this.toggleWorking==1||$(CHV.fn.uploader.selectors.root).is(":animated")||CHV.fn.uploader.is_uploading||($switch.data('login-needed')&&!PF.fn.is_user_logged()))return;this.toggleWorking=1;var uploadBoxHeight=$(CHV.fn.uploader.selectors.root).outerHeight()+"px";var uploadBoxTop=$(CHV.fn.uploader.selectors.root).css("top");var uploadBoxPush=(parseInt(uploadBoxHeight)+parseInt(uploadBoxTop))+"px";var animation={core:!show?("-"+uploadBoxPush):uploadBoxPush,time:500,},callbacks=function(){if(options.reset){CHV.fn.uploader.reset();}
$("#content-listing-wrapper").selectable({filter:PF.obj.listing.selectors.list_item,cancel:".content-empty, .header, #tab-share, #tab-full-info, .viewer-title, .header-link, .top-bar, .content-listing-pagination *, #fullscreen-modal, #top-user, #background-cover, .list-item-desc, .list-item-image-tools, [data-action=load-image], #tab-codes",delay:5,selecting:function(event,ui){var $this=$(ui.selecting);var unselect=$this.hasClass("selected");CHV.fn.list_editor[(unselect?"unselect":"select")+"Item"]($this);},unselecting:function(event,ui){CHV.fn.list_editor.unselectItem($(ui.unselecting));}});};CHV.fn.isCachedImage=function(src){var image=new Image();image.src=src;return image.complete||image.width+image.height>0;};CHV.fn.viewerImageZoomClass=function(){if(CHV.obj.image_viewer.$container.hasClass("jscursor-zoom-in")){CHV.obj.image_viewer.$container.addClass("cursor-zoom-in").removeClass("jscursor-zoom-in");}};CHV.fn.viewerLoadImage=function(){if(CHV.obj.image_viewer.$loading.exists()){CHV.obj.image_viewer.$loading.removeClass("soft-hidden").css({zIndex:2});PF.fn.loading.inline(CHV.obj.image_viewer.$loading,{color:"white",size:"small",center:true,valign:true});CHV.obj.image_viewer.$loading.hide().fadeIn("slow");}
$(CHV.obj.image_viewer.loader).remove();CHV.obj.image_viewer.image.html=CHV.obj.image_viewer.$container.html();CHV.obj.image_viewer.$container.prepend($(CHV.obj.image_viewer.image.html).css({top:0,zIndex:0}));CHV.obj.image_viewer.$container.find("img").eq(0).css("zIndex",1);CHV.obj.image_viewer.$container.find("img").eq(1).attr("src",CHV.obj.image_viewer.image.url).css({width:"100%",height:"auto"});CHV.obj.image_viewer.$container.find("img").eq(1).imagesLoaded(function(){CHV.obj.image_viewer.$container.find("img").eq(1).css({width:"",height:""});CHV.obj.image_viewer.$container.find("img").eq(0).remove();PF.fn.loading.destroy(CHV.obj.image_viewer.$loading);});};CHV.obj.embed_tpl={};CHV.obj.topBar={transparencyScrollToggle:function(){var Y=$(window).scrollTop();$("#top-bar")[(Y>0?"remove":"add")+"Class"]("transparent");}};CHV.fn.uploader={selectors:{root:"#anywhere-upload",queue:"#anywhere-upload-queue",queue_complete:".queue-complete",queue_item:".queue-item",close_cancel:"[data-button=close-cancel]",file:"#anywhere-upload-input",camera:"#anywhere-upload-input-camera",upload_item_template:"#anywhere-upload-item-template",item_progress_bar:"[data-content=progress-bar]",item_progress_percent:"[data-text=progress-percent]",failed_result:"[data-content=failed-upload-result]",fullscreen_mask:"#fullscreen-uploader-mask",dropzone:"#uploader-dropzone",paste:"#anywhere-upload-paste",},isUploading:false,canAdd:true,queueStatus:"ready",files:{},results:{success:[],error:[]},toggleWorking:0,toggle:function(options,args){var $switch=$("[data-action=top-bar-upload]",".top-bar");var show=!$(CHV.fn.uploader.selectors.root).data("shown");var options=$.extend({callback:null,reset:true},options);PF.fn.growl.close(true);PF.fn.close_pops();if(this.toggleWorking==1||$(CHV.fn.uploader.selectors.root).is(":animated")||CHV.fn.uploader.isUploading||($switch.data('login-needed')&&!PF.fn.is_user_logged()))return;this.toggleWorking=1;var uploadBoxHeight=$(CHV.fn.uploader.selectors.root).outerHeight()+"px";var uploadBoxTop=$(CHV.fn.uploader.selectors.root).css("top");var uploadBoxPush=(parseInt(uploadBoxHeight)+parseInt(uploadBoxTop))+"px";var animation={core:!show?("-"+uploadBoxPush):uploadBoxPush,time:500,},callbacks=function(){if(options.reset){CHV.fn.uploader.reset();}
if(PF.obj.follow_scroll.$node.exists()){PF.obj.follow_scroll.$node.removeClass("fixed");PF.obj.follow_scroll.set();}
if(!show){$(CHV.fn.uploader.selectors.root).css({visibility:"hidden"}).addClass("hidden-visibility");}
PF.fn.topMenu.hide();if(typeof options.callback=="function"){options.callback(args);}
@ -112,33 +112,32 @@ if(!$("#top-bar").hasClass("transparent")){fade_slim_shady()}
$(CHV.fn.uploader.selectors.fullscreen_mask).css({opacity:0});setTimeout(function(){$(CHV.fn.uploader.selectors.fullscreen_mask).remove();if($("html").data("followed-scroll")){$("html").addClass("followed-scroll");}},250);var _uploadBoxHeight=$(CHV.fn.uploader.selectors.root).outerHeight();var _uploadBoxPush=(_uploadBoxHeight-parseInt($(CHV.fn.uploader.selectors.root).data("initial-height")))+"px";$(CHV.fn.uploader.selectors.root).css({transform:"translate(0,-"+_uploadBoxPush+")"});setTimeout(function(){$("#top-bar").attr("class",$("#top-bar").data("stock_classes"));$("html").removeClass(($(".follow-scroll-wrapper.position-fixed").exists()?"":"top-bar-box-shadow-none"));},animation.time*1/3);setTimeout(function(){$(CHV.fn.uploader.selectors.root).css({top:""});if($("#top-bar-shade").exists()){fade_slim_shady()}
if($("body#image").exists()){CHV.obj.topBar.transparencyScrollToggle();}
callbacks();$("html").removeClass("overflow-hidden").data({"top-bar-box-shadow-prevent":false});},animation.time);}
$(CHV.fn.uploader.selectors.root).data("shown",show);$switch.toggleClass("current").removeClass("opened");},reset:function(){this.files={};this.is_uploading=false;this.can_add=true;this.results={success:[],error:[]};this.queue_status="ready";$("li",this.selectors.queue).remove();$(this.selectors.anywhere).height("").css({"overflow-y":"","overflow-x":""});$(this.selectors.queue).removeClass(this.selectors.queue_complete.substring(1));$("[data-group=upload-result] textarea",this.selectors.anywhere).prop("value","");$.each(['upload-queue-ready','uploading','upload-result','upload-queue-ready','upload-queue'],function(i,v){$("[data-group="+v+"]").hide();});$("[data-group=upload]",this.selectors.anywhere).show();$("[name=upload-category-id]",this.selectors.root).val("");$("[name=upload-nsfw]",this.selectors.root).prop("checked",this.defaultChecked);$(this.selectors.close_cancel,this.selectors.anywhere).hide().each(function(){if($(this).data("action")=="close-upload")$(this).show();});this.boxSizer(true);},focus:function(callback){if($(this.selectors.fullscreen_mask).exists())return;$("body").append($("<div/>",{id:(this.selectors.fullscreen_mask.replace("#","")),class:"fullscreen soft-black",}).css({top:PF.fn.isDevice("phone")?0:$(CHV.fn.uploader.selectors.root).data("top")}));setTimeout(function(){$(CHV.fn.uploader.selectors.fullscreen_mask).css({opacity:1})
$(CHV.fn.uploader.selectors.root).data("shown",show);$switch.toggleClass("current").removeClass("opened");},reset:function(){this.files={};this.isUploading=false;this.canAdd=true;this.results={success:[],error:[]};this.queueStatus="ready";$("li",this.selectors.queue).remove();$(this.selectors.anywhere).height("").css({"overflow-y":"","overflow-x":""});$(this.selectors.queue).removeClass(this.selectors.queue_complete.substring(1));$("[data-group=upload-result] textarea",this.selectors.anywhere).prop("value","");$.each(['upload-queue-ready','uploading','upload-result','upload-queue-ready','upload-queue'],function(i,v){$("[data-group="+v+"]").hide();});$("[data-group=upload]",this.selectors.anywhere).show();$("[name=upload-category-id]",this.selectors.root).val("");$("[name=upload-nsfw]",this.selectors.root).prop("checked",this.defaultChecked);$(this.selectors.close_cancel,this.selectors.anywhere).hide().each(function(){if($(this).data("action")=="close-upload")$(this).show();});this.boxSizer(true);},focus:function(callback){if($(this.selectors.fullscreen_mask).exists())return;$("body").append($("<div/>",{id:(this.selectors.fullscreen_mask.replace("#","")),class:"fullscreen soft-black",}).css({top:PF.fn.isDevice("phone")?0:$(CHV.fn.uploader.selectors.root).data("top")}));setTimeout(function(){$(CHV.fn.uploader.selectors.fullscreen_mask).css({opacity:1})
setTimeout(function(){if(typeof callback=="function"){callback();}},PF.fn.isDevice(["phone","phablet"])?0:250);},1);},boxSizer:function(forced){if($(this.selectors.root).css("visibility")=="visible"){$("html")[(PF.fn.isDevice(["phone","phablet"])?"add":"remove")+"Class"]("overflow-hidden");}
var doit=$(this.selectors.root).css("visibility")=="visible"||forced;if(!doit)return;$(this.selectors.root).height("");if($(this.selectors.root).height()+$("#top-bar").outerHeight(true)>$(window).height()){$(this.selectors.root).height($(window).height()-$("#top-bar").outerHeight(true)).css({"overflow-y":"scroll","overflow-x":"auto"});$("body").addClass("overflow-hidden");}else{$(this.selectors.root).css("overflow-y","");$("body").removeClass("overflow-hidden");}},pasteURL:function(){var urlvalues=$("[name=urls]","#fullscreen-modal").val();if(urlvalues){CHV.fn.uploader.add({},urlvalues);}},pasteImageHandler:function(e){if($(e.target).is(":input")){return;}
if(typeof e.clipboardData!==typeof undefined&&e.clipboardData.items){var items=e.clipboardData.items;}else{setTimeout(function(){e.clipboardData={};e.clipboardData.items=[];$.each($("img",CHV.fn.uploader.$pasteCatcher),function(i,v){e.clipboardData.items.push(PF.fn.dataURItoBlob($(this).attr("src")));});$(CHV.fn.uploader.selectors.paste).html("");return CHV.fn.uploader.pasteImageHandler(e);},1);}
if(items){for(var i=0;i<items.length;i++){if(items[i].type.indexOf("image")!==-1){var file=items[i]instanceof Blob?items[i]:items[i].getAsFile();var reader=new FileReader();reader.onload=function(evt){var uploaderIsVisible=$(CHV.fn.uploader.selectors.root).data("shown");file.name=PF.fn._s('Clipboard image')+' '+PF.fn.getDateTime();var file_evt={originalEvent:{dataTransfer:{files:[file]},preventDefault:function(){},stopPropagation:function(){},clipboard:true,dataURL:evt.target.result,name:file.name}};if(!uploaderIsVisible){CHV.fn.uploader.toggle({callback:function(){CHV.fn.uploader.add(file_evt);}});}else{CHV.fn.uploader.add(file_evt);}};reader.readAsDataURL(file);}}}},item_add_id:0,clipboardImages:[],add:function(e,urls){var md5;if(typeof CHV.obj.config!=="undefined"&&typeof CHV.obj.config.image!=="undefined"&&CHV.obj.config.image.max_filesize!=="undefined"){this.options.max_filesize=CHV.obj.config.image.max_filesize;}
if(!this.can_add){var e=e.originalEvent;e.preventDefault();e.stopPropagation();return false;};$fileinput=$(this.selectors.file);$fileinput.replaceWith($fileinput=$fileinput.clone(true));var item_queue_template=$(this.selectors.upload_item_template).html();var files=[];if(typeof urls==typeof undefined){var e=e.originalEvent;e.preventDefault();e.stopPropagation();files=e.dataTransfer||e.target;files=$.makeArray(files.files);if(e.clipboard){md5=PF.fn.md5(e.dataURL);if($.inArray(md5,this.clipboardImages)!=-1){return null;}
if(items){for(var i=0;i<items.length;i++){if(items[i].type.indexOf("image")!==-1){var file=items[i]instanceof Blob?items[i]:items[i].getAsFile();var reader=new FileReader();reader.onload=function(evt){var uploaderIsVisible=$(CHV.fn.uploader.selectors.root).data("shown");file.name=PF.fn._s('Clipboard image')+' '+PF.fn.getDateTime();var file_evt={originalEvent:{dataTransfer:{files:[file]},preventDefault:function(){},stopPropagation:function(){},clipboard:true,dataURL:evt.target.result,name:file.name}};if(!uploaderIsVisible){CHV.fn.uploader.toggle({callback:function(){CHV.fn.uploader.add(file_evt);}});}else{CHV.fn.uploader.add(file_evt);}};reader.readAsDataURL(file);}}}},filesAddId:0,clipboardImages:[],add:function(e,urls){var md5;if(!this.canAdd){var e=e.originalEvent;e.preventDefault();e.stopPropagation();return false;};$fileinput=$(this.selectors.file);$fileinput.replaceWith($fileinput=$fileinput.clone(true));var item_queue_template=$(this.selectors.upload_item_template).html();var files=[];if(typeof urls==typeof undefined){var e=e.originalEvent;e.preventDefault();e.stopPropagation();files=e.dataTransfer||e.target;files=$.makeArray(files.files);if(e.clipboard){md5=PF.fn.md5(e.dataURL);if($.inArray(md5,this.clipboardImages)!=-1){return null;}
this.clipboardImages.push(md5);}
var failed_files=[];for(var i=0;i<files.length;i++){var file=files[i];var image_type_str;if(typeof file.type=="undefined"||file.type==""){image_type_str=file.name.substr(file.name.lastIndexOf('.')+1).toLowerCase();}else{image_type_str=file.type.replace("image/","");}
if(file.size>CHV.obj.config.image.max_filesize.getBytes()){failed_files.push({uid:i,name:file.name.truncate_middle()+" - "+PF.fn._s("File too big.")});continue;}
if(CHV.fn.uploader.options.image_types.indexOf(image_type_str)==-1&&/android/i.test(navigator.userAgent)==false){failed_files.push({uid:i,name:file.name.truncate_middle()+" - "+PF.fn._s("Invalid or unsupported file format.")});continue;}
if(CHV.obj.config.upload.image_types.indexOf(image_type_str)==-1&&/android/i.test(navigator.userAgent)==false){failed_files.push({uid:i,name:file.name.truncate_middle()+" - "+PF.fn._s("Invalid or unsupported file format.")});continue;}
if(md5){file.md5=md5;}
file.fromClipboard=e.clipboard==true;file.uid=i;}
for(var i=0;i<failed_files.length;i++){var failed_file=failed_files[i];files.splice(failed_file.id,1)}
if(failed_files.length>0&&files.length==0){var failed_message='';for(var i=0;i<failed_files.length;i++){failed_message+="<li>"+failed_files[i].name+"</li>";}
PF.fn.modal.simple({title:PF.fn._s("Some files couldn't be added"),message:"<ul>"+"<li>"+failed_message+"</ul>"});return;}
if(files.length==0){return;}}else{files=urls.match_urls();if(!files)return;files=files.array_unique();files=$.map(files,function(file,i){return{uid:i,name:file,url:file};});}
if($.isEmptyObject(this.files)){for(var i=0;i<files.length;i++){this.files[files[i].uid]=files[i];this.item_add_id++;}}else{var currentfiles=[];for(var key in this.files){if(typeof this.files[key]=="undefined"||typeof this.files[key]=="function")continue;currentfiles.push(encodeURI(this.files[key].name));}
if(files.length==0){return;}}else{urls=urls.replace(/(<([^>]+)>)/g,'').replace(/(\[([^\]]+)\])/g,'');files=urls.match_urls();if(!files)return;files=files.array_unique();files=$.map(files,function(file,i){return{uid:i,name:file,url:file};});}
if($.isEmptyObject(this.files)){for(var i=0;i<files.length;i++){this.files[files[i].uid]=files[i];this.filesAddId++;}}else{var currentfiles=[];for(var key in this.files){if(typeof this.files[key]=="undefined"||typeof this.files[key]=="function")continue;currentfiles.push(encodeURI(this.files[key].name));}
files=$.map(files,function(file,i){if($.inArray(encodeURI(file.name),currentfiles)!=-1){return null;}
file.uid=CHV.fn.uploader.item_add_id+i;CHV.fn.uploader.item_add_id++;return file;});for(var i=0;i<files.length;i++){this.files[files[i].uid]=files[i];}}
$(this.selectors.queue,this.selectors.root).append(item_queue_template.repeat(files.length));$(this.selectors.queue+" "+this.selectors.queue_item+":not([data-id])",this.selectors.root).hide();$(this.selectors.close_cancel,this.selectors.root).hide().each(function(){if($(this).data("action")=="close-upload")$(this).show();});var failed_before=failed_files,failed_files=[],j=0,default_options={canvas:true,};function CHVLoadImage(i){if(typeof i==typeof undefined){var i=0;}
file.uid=CHV.fn.uploader.filesAddId+i;CHV.fn.uploader.filesAddId++;return file;});for(var i=0;i<files.length;i++){this.files[files[i].uid]=files[i];}}
$(this.selectors.queue,this.selectors.root).append(item_queue_template.repeat(files.length));$(this.selectors.queue+" "+this.selectors.queue_item+":not([data-id])",this.selectors.root).hide();$(this.selectors.close_cancel,this.selectors.root).hide().each(function(){if($(this).data("action")=="close-upload")$(this).show();});var failed_before=failed_files,failed_files=[],j=0,default_options={canvas:true,maxWidth:600};function CHVLoadImage(i){if(typeof i==typeof undefined){var i=0;}
if(!(i in files)){return;}
var file=files[i];$(CHV.fn.uploader.selectors.queue_item+":not([data-id]) .load-url",CHV.fn.uploader.selectors.queue)[typeof file.url!=="undefined"?"show":"remove"]();loadImage.parseMetaData(file.url?file.url:file,function(data){$(CHV.fn.uploader.selectors.queue_item+":not([data-id]) .preview:empty",CHV.fn.uploader.selectors.queue).first().closest("li").attr("data-id",file.uid);loadImage(file.url?file.url:file,function(img){++j;var $queue_item=$(CHV.fn.uploader.selectors.queue_item+"[data-id="+(file.uid)+"]",CHV.fn.uploader.selectors.queue);if(img.type==="error"){failed_files.push({id:file.uid,name:file.name.truncate_middle()});}else{if(!$("[data-group=upload-queue]",CHV.fn.uploader.selectors.root).is(":visible")){$("[data-group=upload-queue]",CHV.fn.uploader.selectors.root).css("display","block");}
var mimetype="image/jpeg";if(typeof data.buffer!==typeof undefined){var buffer=(new Uint8Array(data.buffer)).subarray(0,4);var header="";for(var i=0;i<buffer.length;i++){header+=buffer[i].toString(16);}
var header_to_mime={'89504e47':'image/png','47494638':'image/gif','ffd8ffe0':'image/jpeg',}
$.each(['ffd8ffe1','ffd8ffe2'],function(i,v){header_to_mime[v]=header_to_mime['ffd8ffe0'];});if(typeof header_to_mime[header]!==typeof undefined){mimetype=header_to_mime[header];}}
var title=null;if(typeof file.name!==typeof undefined){var basename=PF.fn.baseName(file.name);title=$.trim(basename.substring(0,100).capitalizeFirstLetter());}
CHV.fn.uploader.files[file.uid].parsedMeta={title:title,width:img.width,height:img.height,canvas:img,mimetype:mimetype,};var img=loadImage.scale(img,{maxWidth:600});$queue_item.show();$("[data-group=upload-queue-ready]",CHV.fn.uploader.selectors.root).show();$("[data-group=upload]",CHV.fn.uploader.selectors.root).hide();$queue_item.find(".load-url").remove();$queue_item.find(".preview").removeClass("soft-hidden").show().append(img);$img=$queue_item.find(".preview").find("img,canvas");$img.attr("class","canvas");queue_item_h=$queue_item.height();queue_item_w=$queue_item.width();var img_w=parseInt($img.attr("width"))||$img.width();var img_h=parseInt($img.attr("height"))||$img.height();var img_r=img_w/img_h;$img.hide();if(img_w>img_h||img_w==img_h){var queue_img_h=img_h<queue_item_h?img_h:queue_item_h;if(img_w>img_h){$img.height(queue_img_h).width(queue_img_h*img_r);}}
CHV.fn.uploader.files[file.uid].parsedMeta={title:title,width:img.width,height:img.height,mimetype:mimetype,};var img=loadImage.scale(img,{maxWidth:600});$queue_item.show();$("[data-group=upload-queue-ready]",CHV.fn.uploader.selectors.root).show();$("[data-group=upload]",CHV.fn.uploader.selectors.root).hide();$queue_item.find(".load-url").remove();$queue_item.find(".preview").removeClass("soft-hidden").show().append(img);$img=$queue_item.find(".preview").find("img,canvas");$img.attr("class","canvas");queue_item_h=$queue_item.height();queue_item_w=$queue_item.width();var img_w=parseInt($img.attr("width"))||$img.width();var img_h=parseInt($img.attr("height"))||$img.height();var img_r=img_w/img_h;$img.hide();if(img_w>img_h||img_w==img_h){var queue_img_h=img_h<queue_item_h?img_h:queue_item_h;if(img_w>img_h){$img.height(queue_img_h).width(queue_img_h*img_r);}}
if(img_w<img_h||img_w==img_h){var queue_img_w=img_w<queue_item_w?img_w:queue_item_w;if(img_w<img_h){$img.width(queue_img_w).height(queue_img_w/img_r);}}
if(img_w==img_h){$img.height(queue_img_h).width(queue_img_w);}
$img.css({marginTop:-$img.height()/2,marginLeft:-$img.width()/2}).show();CHV.fn.uploader.boxSizer();}
@ -146,16 +145,20 @@ if(j==files.length){if(typeof failed_before!=="undefined"){failed_files=failed_f
PF.fn.loading.destroy("fullscreen");if(failed_files.length>0){var failed_message="";for(var i=0;i<failed_files.length;i++){failed_message+="<li>"+failed_files[i].name+"</li>";delete CHV.fn.uploader.files[failed_files[i].uid];$("li[data-id="+failed_files[i].uid+"]",CHV.fn.uploader.selectors.queue).find("[data-action=cancel]").click()}
PF.fn.modal.simple({title:PF.fn._s("Some files couldn't be added"),message:'<ul>'+failed_message+'</ul>'});}else{CHV.fn.uploader.focus();}
CHV.fn.uploader.boxSizer();}},$.extend({},default_options,{orientation:data.exif?data.exif.get("Orientation"):1}));setTimeout(function(){CHVLoadImage(i+1);},25);});}
PF.fn.loading.fullscreen();CHVLoadImage();},queueSize:function(){$("[data-text=queue-objects]",this.selectors.root).text(PF.fn._n("image","images",Object.size(this.files)));$("[data-text=queue-size]",this.selectors.root).text(Object.size(this.files));},queueProgress:function(e){var total_queue_items_done=$("> .completed, > .failed",this.selectors.queue).length,total_queue_items=$(this.selectors.queue).children().length,total_queueProgress=parseInt(100*(parseFloat(total_queue_items_done/total_queue_items)+parseFloat((e.loaded / e.total)/total_queue_items)));$("[data-text=queue-progress]",this.selectors.root).text(total_queueProgress);},upload:function($queue_item){var id=$queue_item.data("id"),f=this.files[id],queue_is_url=typeof f.url!=="undefined";var source=queue_is_url?f.url:f;var hasForm=typeof f.formValues!==typeof undefined;if(typeof f=="undefined"){if($queue_item.next().exists()){this.upload($queue_item.next());}
PF.fn.loading.fullscreen();CHVLoadImage();},queueSize:function(){$("[data-text=queue-objects]",this.selectors.root).text(PF.fn._n("image","images",Object.size(this.files)));$("[data-text=queue-size]",this.selectors.root).text(Object.size(this.files));},queueProgress:function(e,id){var queue_size=Object.keys(this.files).length;this.files[id].progress=e.loaded / e.total;var progress=0;for(var i=0;i<queue_size;i++){if(typeof this.files[i]==typeof undefined||!('progress'in this.files[i]))continue;progress+=this.files[i].progress;}
$("[data-text=queue-progress]",this.selectors.root).text(parseInt(100*progress / queue_size));},uploadThreads:0,uploadParsedIds:[],upload:function($queue_item){var id=$queue_item.data("id");var nextId=$queue_item.next().exists()?$queue_item.next().data("id"):false;if($.inArray(id,this.uploadParsedIds)!==-1){if($queue_item.next().exists()){this.upload($queue_item.next());}
return;}
$(this.selectors.close_cancel,this.selectors.root).hide().each(function(){if($(this).data("action")=="cancel-upload")$(this).show();});this.is_uploading=true;if(!queue_is_url&&f.parsedMeta.mimetype!=="image/gif"&&typeof f.formValues!==typeof undefined&&f.formValues.width!=f.parsedMeta.width){isBlob=true;var canvas=$("<canvas />")[0];canvas.width=f.formValues.width;canvas.height=f.formValues.height;var ctx=canvas.getContext("2d");ctx.drawImage(f.parsedMeta.canvas,0,0,canvas.width,canvas.height);source=PF.fn.dataURItoBlob(canvas.toDataURL(f.parsedMeta.mimetype));};var form=new FormData();var formData={source:null,type:queue_is_url?"url":"file",action:"upload",privacy:$("[data-privacy]",this.selectors.root).first().data("privacy"),timestamp:this.timestamp,auth_token:PF.obj.config.auth_token,category_id:$("[name=upload-category-id]",this.selectors.root).val()||null,nsfw:$("[name=upload-nsfw]",this.selectors.root).prop("checked")?1:0};if(queue_is_url){formData.source=source;}else{form.append("source",source,f.name);}
if(hasForm){$.each(f.formValues,function(i,v){formData[i.replace(/image_/g,"")]=v;});};$.each(formData,function(i,v){form.append(i,v);});this.files[id].xhr=new XMLHttpRequest();$queue_item.removeClass("waiting");if(!queue_is_url){this.files[id].xhr.upload.onprogress=function(e){if(e.lengthComputable){CHV.fn.uploader.queueProgress(e);percentComplete=parseInt((e.loaded / e.total)*100);$(CHV.fn.uploader.selectors.item_progress_percent,$queue_item).text(percentComplete);$(CHV.fn.uploader.selectors.item_progress_bar,$queue_item).width(100-percentComplete+"%");if(percentComplete==100){$(CHV.fn.uploader.selectors.item_progress_percent,$queue_item).text("");CHV.fn.uploader.itemLoading($queue_item);}}}}else{this.queueSize();this.queueProgress({loaded:1,total:1});this.itemLoading($queue_item);}
this.files[id].xhr.onreadystatechange=function(){var is_error=false;if(this.readyState==4&&typeof CHV.fn.uploader.files[id].xhr!=="undefined"&&CHV.fn.uploader.files[id].xhr.status!==0){$(".loading-indicator",$queue_item).remove();$queue_item.removeClass("waiting uploading");try{var JSONresponse=this.responseType!=="json"?JSON.parse(this.response):this.response;if(typeof JSONresponse!=="undefined"&&this.status==200){$("[data-group=image-link]",$queue_item).attr("href",JSONresponse.image.url_viewer);}else{if(JSONresponse.error.context=="PDOException"){JSONresponse.error.message="Database error";}
var self=this;this.uploadParsedIds.push(id);var f=this.files[id];var queue_is_url=typeof f.url!=="undefined";var source=queue_is_url?f.url:f;var hasForm=typeof f.formValues!==typeof undefined;if(typeof f=="undefined"){if($queue_item.next().exists()){this.upload($queue_item.next());}
return;}
$(this.selectors.close_cancel,this.selectors.root).hide().each(function(){if($(this).data("action")=="cancel-upload")$(this).show();});this.uploadThreads+=1;if(this.uploadThreads<CHV.obj.config.upload.threads&&nextId!==false){this.upload($queue_item.next());}
this.isUploading=true;var form=new FormData();var formData={source:null,type:queue_is_url?"url":"file",action:"upload",privacy:$("[data-privacy]",this.selectors.root).first().data("privacy"),timestamp:this.timestamp,auth_token:PF.obj.config.auth_token,category_id:$("[name=upload-category-id]",this.selectors.root).val()||null,nsfw:$("[name=upload-nsfw]",this.selectors.root).prop("checked")?1:0};if(queue_is_url){formData.source=source;}else{form.append("source",source,f.name);}
if(hasForm){$.each(f.formValues,function(i,v){formData[i.replace(/image_/g,"")]=v;});};$.each(formData,function(i,v){form.append(i,v);});this.files[id].xhr=new XMLHttpRequest();$queue_item.removeClass("waiting");if(!queue_is_url){this.files[id].xhr.upload.onprogress=function(e){if(e.lengthComputable){CHV.fn.uploader.queueProgress(e,id);percentComplete=parseInt((e.loaded / e.total)*100);$(CHV.fn.uploader.selectors.item_progress_percent,$queue_item).text(percentComplete);$(CHV.fn.uploader.selectors.item_progress_bar,$queue_item).width(100-percentComplete+"%");if(percentComplete==100){$(CHV.fn.uploader.selectors.item_progress_percent,$queue_item).text("");CHV.fn.uploader.itemLoading($queue_item);}}}}else{this.queueSize();this.queueProgress({loaded:1,total:1},id);this.itemLoading($queue_item);}
this.files[id].xhr.onreadystatechange=function(){var is_error=false;if(this.readyState==4&&typeof CHV.fn.uploader.files[id].xhr!=="undefined"&&CHV.fn.uploader.files[id].xhr.status!==0){self.uploadThreads-=1;$(".loading-indicator",$queue_item).remove();$queue_item.removeClass("waiting uploading");try{var JSONresponse=this.responseType!=="json"?JSON.parse(this.response):this.response;if(typeof JSONresponse!=="undefined"&&this.status==200){$("[data-group=image-link]",$queue_item).attr("href",JSONresponse.image.url_viewer);}else{if(JSONresponse.error.context=="PDOException"){JSONresponse.error.message="Database error";}
JSONresponse.error.message=CHV.fn.uploader.files[id].name.truncate_middle()+" - "+JSONresponse.error.message;}
CHV.fn.uploader.results[this.status==200?"success":"error"].push(JSONresponse);if(this.status!==200)is_error=true;}catch(err){is_error=true;var err_handle;if(typeof JSONresponse=="undefined"){err_handle={status:500,statusText:"Internal server error"}}else{err_handle={status:400,statusText:JSONresponse.error.message}}
JSONresponse={status_code:err_handle.status,error:{message:CHV.fn.uploader.files[id].name.truncate_middle()+" - Server error ("+err_handle.statusText+")",code:err_handle.status,context:"XMLHttpRequest"},status_txt:err_handle.statusText};CHV.fn.uploader.results.error.push(JSONresponse);console.log("server error",JSONresponse);}
$queue_item.addClass(!is_error?"completed":"failed");if(typeof JSONresponse.error!=="undefined"&&typeof JSONresponse.error.message!=="undefined"){$queue_item.attr("rel","tooltip").data("tiptip","top").attr("title",JSONresponse.error.message);PF.fn.bindtipTip($queue_item);}
if($queue_item.next().exists()){CHV.fn.uploader.upload($queue_item.next());$(CHV.fn.uploader.selectors.close_cancel,CHV.fn.uploader.selectors.root).hide().each(function(){if($(this).data("action")=="cancel-upload-remaining")$(this).show();});}else{CHV.fn.uploader.is_uploading=false;CHV.fn.uploader.displayResults();}
if(self.uploadThreads<CHV.obj.config.upload.threads&&nextId!==false){CHV.fn.uploader.upload($queue_item.next());$(CHV.fn.uploader.selectors.close_cancel,CHV.fn.uploader.selectors.root).hide().each(function(){if($(this).data("action")=="cancel-upload-remaining"){$(this).show();}});}else{CHV.fn.uploader.isUploading=false;CHV.fn.uploader.displayResults();}
$(".done",$queue_item).fadeOut();}};this.files[id].xhr.open("POST",PF.obj.config.json_api,true);this.files[id].xhr.setRequestHeader("Accept","application/json");this.files[id].xhr.send(form);},itemLoading:function($queue_item){PF.fn.loading.inline($(".progress",$queue_item),{color:"#FFF",size:"normal",center:true,position:"absolute",shadow:true});$("[data-action=cancel], [data-action=edit]",$queue_item).hide();},displayResults:function(){var group_result="[data-group=upload-result][data-result=%RESULT%]",result_types=["error","mixed","success"],results={};for(var i=0;i<result_types.length;i++){results[result_types[i]]=group_result.replace("%RESULT%",result_types[i]);}
if(this.results.error.length>0){var error_files=[];for(var i=0;i<this.results.error.length;i++){error_files.push(this.results.error[i].error.message);}
if(Object.size(error_files)>0){$(this.selectors.failed_result).html("<li>"+error_files.join("</li><li>")+"</li>");}}else{$(results.error,this.selectors.root).hide();}
@ -163,7 +166,7 @@ if(CHV.obj.config.upload.redirect_single_upload&&this.results.success.length==1&
$("[data-text=queue-progress]",this.selectors.root).text(100);$("[data-group=uploading]",this.selectors.root).hide();$(this.selectors.close_cancel,this.selectors.root).hide().each(function(){if($(this).data("action")=="close-upload")$(this).show();});$(this.selectors.queue).addClass(this.selectors.queue_complete.substring(1));if(this.results.success.length>0&&$("[data-group=upload-result] textarea",this.selectors.root).exists()){CHV.fn.fillEmbedCodes(this.results.success,CHV.fn.uploader.selectors.root,"val");}
if(this.results.success.length>0&&this.results.error.length>0){$(results.mixed+", "+results.success,this.selectors.root).show();}else if(this.results.success.length>0){$(results.success,this.selectors.root).show();}else if(this.results.error.length>0){$(results.error,this.selectors.root).show();}
if($(results.success,this.selectors.root).is(":visible")){$(results.success,this.selectors.root).find("[data-group=user], [data-group=guest]").hide();$(results.success,this.selectors.root).find("[data-group="+(PF.fn.is_user_logged()?"user":"guest")+"]").show();if(typeof this.results.success[0].image.album!=="undefined"){$("[data-text=upload-target]").text(this.results.success[0].image.album.name);$("[data-link=upload-target]").attr("href",this.results.success[0].image.album.url);}}
this.boxSizer();this.queue_status="done";}};CHV.fn.fillEmbedCodes=function(elements,parent,fn){if(typeof fn=="undefined"){fn="val";}
this.boxSizer();this.queueStatus="done";}};CHV.fn.fillEmbedCodes=function(elements,parent,fn){if(typeof fn=="undefined"){fn="val";}
$.each(elements,function(key,value){var image=value.image;if(!image.medium){image.medium={};var imageProp=["filename","name","width","height","extension","size","size_formatted","url"];for(var i=0;i<imageProp.length;i++){image.medium[imageProp[i]]=image[imageProp[i]];}}
var flatten_image=Object.flatten(image);$.each(CHV.obj.embed_tpl,function(key,value){$.each(value.options,function(k,v){var embed=v,$embed=$("textarea[name="+k+"]",parent),template=embed.template;for(var i in flatten_image){if(!flatten_image.hasOwnProperty(i)){continue;}
template=template.replace(new RegExp("%"+i.toUpperCase()+"%","g"),flatten_image[i]);}

View File

@ -411,8 +411,8 @@ class Album {
];
try {
$db = DB::getInstance();
$flood_db = $db->queryFetchSingle("
SELECT
$flood_db = $db->queryFetchSingle(
"SELECT
COUNT(IF(album_date_gmt >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 MINUTE), 1, NULL)) AS minute,
COUNT(IF(album_date_gmt >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 HOUR), 1, NULL)) AS hour,
COUNT(IF(album_date_gmt >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 DAY), 1, NULL)) AS day,
@ -450,6 +450,8 @@ class Album {
return ['flood' => TRUE, 'limit' => $flood_limit[$flood_by], 'count' => $flood_db[$flood_by], 'by' => $flood_by];
}
return FALSE;
}
}

View File

@ -61,13 +61,6 @@ class Image {
'LEFT JOIN '.$tables['albums'].' ON '.$tables['images'].'.image_album_id = '.$tables['albums'].'.album_id'
];
if($requester) {
if(!is_array($requester)) {
$requester = User::getSingle($requester, 'id');
}
$joins[] = 'LEFT JOIN '.$tables['likes'].' ON '.$tables['likes'].'.like_content_type = "image" AND '.$tables['images'].'.image_id = '.$tables['likes'].'.like_content_id AND '.$tables['likes'].'.like_user_id = ' . $requester['id'];
}
$query .= implode("\n", $joins) . "\n";
$query .= 'WHERE image_id=:image_id;'."\n";
@ -452,6 +445,12 @@ class Image {
// Resizable watermark image
try {
$watermark_tempnam = @tempnam(sys_get_temp_dir(), 'chvtemp');
if(!$watermark_tempnam) {
$watermark_tempnam = @tempnam(dirname($image_path), 'chvtemp');
}
if(!$watermark_tempnam) {
throw new Exception("Can't tempnam a watermak file", 400);
}
self::resize($options['file'], dirname($watermark_tempnam), basename($watermark_tempnam), ['width' => $watermark_new_width]);
$watermark_temp = $watermark_tempnam . '.png';
$watermark_src = imagecreatefrompng($watermark_temp);
@ -888,18 +887,24 @@ class Image {
// From Exif
$title_from_exif = $image_upload['source']['image_exif']['ImageDescription'] ? trim($image_upload['source']['image_exif']['ImageDescription']) : NULL;
if($title_from_exif) {
$image_insert_values['title'] = $title_from_exif;
// Get rid of any unicode stuff
$title_from_exif = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $title_from_exif);
$image_title = $title_from_exif;
} else {
// From filename
$title_from_filename = mb_substr(preg_replace('/[-_\s]+/', ' ', trim($image_upload['source']['name'])), 0, 100, 'UTF-8');
$image_insert_values['title'] = ucfirst($title_from_filename);
$title_from_filename = preg_replace('/[-_\s]+/', ' ', trim($image_upload['source']['name']));
$image_title = $title_from_filename;
}
$image_insert_values['title'] = $image_title;
}
if($filenaming == 'id' and $target_id) { // Insert as a reserved ID
$image_insert_values['id'] = $target_id;
}
// Trim image_title to the actual DB limit
$image_insert_values['title'] = mb_substr($image_insert_values['title'], 0, 100, 'UTF-8');
$uploaded_id = self::insert($image_upload, $image_insert_values);
if($filenaming == 'id') {
@ -1068,7 +1073,7 @@ class Image {
return $insert;
} catch(Exception $e) {
throw new ImageException($e->getMessage(), 400);
throw new ImageException($e->getMessage(), $e->getCode());
}
}
@ -1106,7 +1111,6 @@ class Image {
public static function delete($id, $update_user=TRUE) {
try {
$image = self::getSingle($id, FALSE, TRUE);
$disk_space_used = $image['size'] + $image['thumb']['size'] + $image['medium']['size'];
@ -1136,7 +1140,7 @@ class Image {
]);
// Remove "liked" counter for each user who liked this image
DB::queryExec('UPDATE '.DB::getTable('users').' INNER JOIN '.DB::getTable('likes').' ON user_id = like_user_id AND like_content_type = "image" AND like_content_id = '.$image['id'].' SET user_liked = GREATEST(user_liked - 1, 0);');
DB::queryExec('UPDATE '.DB::getTable('users').' INNER JOIN '.DB::getTable('likes').' ON user_id = like_user_id AND like_content_type = "image" AND like_content_id = '.$image['id'].' SET user_liked = GREATEST(cast(user_liked AS SIGNED) - 1, 0);');
if(isset($image['user']['id'])) {
// Detect autolike

View File

@ -210,7 +210,7 @@ class Imageresize {
@copy($this->source, $this->resized_file);
return;
}
@ini_set('gd.jpeg_ignore_warning', 1);
switch($this->file_extension) {
case 'gif':
$src = imagecreatefromgif($this->source);

View File

@ -233,7 +233,8 @@ class Listing {
}
$query = 'SELECT * FROM (SELECT * FROM ' . $base_table . $join . $this->where . $order_by . $limit . ') ' . $base_table . ' ' . "\n";
$query .= implode("\n", $joins[$this->type]) . "\n";
$query .= implode("\n", $joins[$this->type]);
$query .= $order_by;
}
try {

View File

@ -34,6 +34,7 @@ class Settings {
$v = DB::formatRow($v);
$value = $v['value'];
$default = $v['default'];
// Fix those booleans!
if($v['typeset'] == 'bool') {
$value = (bool) $value == 1;
$default = (bool) $default == 1;
@ -53,8 +54,13 @@ class Settings {
//throw new Exception("Can't find any DB setting. Table seems to be empty.", 400);
}
// Inject the missing settings
$injected = [];
// Inject the missing settings (hooks since v3.8.3)
$injected = [
// 1.0.3
'upload_enabled_image_formats' => 'jpg,png,bmp,gif',
'upload_threads' => '2',
'enable_automatic_updates_check'=> 1,
];
// Default listing thing
$device_to_columns = [
@ -121,6 +127,8 @@ class Settings {
// 3.6.5
'image_title_max_length' => 100,
'album_name_max_length' => 100,
// 3.8.4
'upload_available_image_formats' => 'jpg,png,bmp,gif'
]);
if(!$settings['active_storage']) {

View File

@ -169,6 +169,18 @@ class Upload {
}
public static function getAvailableImageFormats() {
return explode(',', Settings::get('upload_available_image_formats'));
}
public static function getEnabledImageFormats() {
$formats = explode(',', Settings::get('upload_enabled_image_formats'));
if(in_array('jpg', $formats)) {
$formats[] = 'jpeg';
}
return $formats;
}
/**
* validate_input aka "first stage validation"
* This checks for valid input source data
@ -185,33 +197,20 @@ class Upload {
}
// Handle flood
$flood = $this->handleFlood();
$flood = self::handleFlood();
if($flood) {
throw new UploadException(strtr('Flood detected. You can only upload %limit% images per %time%', ['%limit%' => $flood['limit'], '%time%' => $flood['by']]), 130);
}
// Validate $source
if($this->type == 'file') {
if(count($this->source) < 5) { // Valid $_FILES ?
throw new UploadException("Invalid file source", 120);
}
/*
if(!$this->isValidImageExtension($this->source["name"])) { // Basic .extension filter
throw new UploadException("Invalid file extension", 121);
}
*/
} else if($this->type == "url") {
if(!G\is_image_url($this->source) && !G\is_url($this->source)) {
throw new UploadException("Invalid image URL", 122);
}
// Removing this saves like 1 second
/*if(!G\is_valid_url($this->source)) {
throw new UploadException("can't reach target image URL", 123);
}*/
}
// Validate $destination
@ -353,6 +352,11 @@ class Upload {
throw new UploadException("Invalid image", 311);
}
// Allowed image format?
if(!in_array($this->source_image_fileinfo['extension'], self::getEnabledImageFormats())) {
throw new UploadException("Invalid image format", 313);
}
// Mime
if(!$this->isValidImageMime($this->source_image_fileinfo["mime"])) {
throw new UploadException("Invalid image mimetype", 312);
@ -376,12 +380,12 @@ class Upload {
}
// Handle flood uploads
protected function handleFlood() {
protected static function handleFlood() {
$logged_user = Login::getUser();
if(!getSetting('flood_uploads_protection') or $logged_user['is_admin']) {
return false;
if(!getSetting('flood_uploads_protection') || $logged_user['is_admin']) {
return FALSE;
}
$flood_limit = [];
@ -391,8 +395,8 @@ class Upload {
try {
$db = DB::getInstance();
$flood_db = $db->queryFetchSingle("
SELECT
$flood_db = $db->queryFetchSingle(
"SELECT
COUNT(IF(image_date_gmt >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 MINUTE), 1, NULL)) AS minute,
COUNT(IF(image_date_gmt >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 HOUR), 1, NULL)) AS hour,
COUNT(IF(image_date_gmt >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 DAY), 1, NULL)) AS day,
@ -432,10 +436,7 @@ class Upload {
return ['flood' => TRUE, 'limit' => $flood_limit[$flood_by], 'count' => $flood_db[$flood_by], 'by' => $flood_by];
}
}
protected function isValidImageExtension($filename) {
return preg_match('/^.*\.(?:jpe?g|gif|png|bmp)$/i', $filename);
return FALSE;
}
protected function isValidImageMime($mime) {

View File

@ -179,6 +179,17 @@ class User {
if(empty($values['registration_ip'])) {
$values['registration_ip'] = G\get_client_ip();
}
// Detect flood (son 48 horas que hay que aprovechar)
if(!Login::getUser()['is_admin']) {
$db = DB::getInstance();
$db->query('SELECT COUNT(*) c FROM ' . DB::getTable('users') . ' WHERE user_registration_ip=:ip AND user_status != "valid" AND user_date_gmt >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 2 DAY)');
$db->bind(':ip', $values['registration_ip']);
if($db->fetchSingle()['c'] > 5) {
throw new Exception('Flood detected', 666); // I left alone, my mind was blank...
}
}
$user_id = DB::insert('users', $values);
// Track stats
Stat::track([
@ -189,7 +200,7 @@ class User {
]);
if(isset($_SESSION['guest_uploads']) and count($_SESSION['guest_uploads']) > 0) {
try {
$db = G\DB::getInstance();
$db = DB::getInstance();
$db->query('UPDATE ' . DB::getTable('images') . ' SET image_user_id=' . $user_id . ' WHERE image_id IN (' . implode(',', $_SESSION['guest_uploads']) . ')');
$db->exec();
// Get user actual image count
@ -340,10 +351,10 @@ class User {
public static function delete($user) {
try {
if(!is_array($user)) {
$user = self::getSingle($user, 'id', true);
$user = self::getSingle($user, 'id', TRUE);
}
// Delete content user image folder
$user_images_path = CHV_PATH_CONTENT_IMAGES_USERS.$user['id_encoded'];
$user_images_path = CHV_PATH_CONTENT_IMAGES_USERS . $user['id_encoded'];
if(!@unlink($user_images_path)) {
$files = glob($user_images_path.'/{,.}*', GLOB_BRACE);
foreach($files as $file){
@ -403,6 +414,7 @@ class User {
'%table_follows'=> DB::getTable('follows'),
'%user_id' => $user['id'],
]);
DB::queryExec($sql);
DB::delete('albums', ['user_id' => $user['id']]); // Delete albums DB
@ -419,6 +431,7 @@ class User {
public static function statusRedirect($status) {
if(isset($status) and $status != NULL and $status !== 'valid') {
if($status == 'awaiting-email') $status = 'email-needed';
G\redirect('account/'.$status);
}
}
@ -565,6 +578,17 @@ class User {
return preg_replace('#<|>#', '', $name);
}
// Clean unconfirmed accounts
public static function cleanup() {
$db = DB::getInstance();
$db->query('SELECT * FROM ' . DB::getTable('users') . ' WHERE user_status IN ("awaiting-confirmation", "awaiting-email") AND user_date_gmt <= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 2 DAY) ORDER BY user_id DESC LIMIT 5'); // Only 5 entries per round, this is an expensive job
$users = $db->fetchAll();
foreach($users as $user) {
$user = self::formatArray($user);
self::delete($user);
}
}
}
class UserException extends Exception {}

View File

@ -679,7 +679,7 @@ function isSafeToExecute($max_execution_time=NULL, $options=[]) {
function checkUpdates() {
try {
if(is_null(getSetting('update_check_datetimegmt')) || G\datetime_add(getSetting('update_check_datetimegmt'), 'P1D') < G\datetimegmt()) {
@set_time_limit(180); // Don't run forever
@set_time_limit(60); // Don't run forever
$safe_time = 5;
$max_execution_time = ini_get('max_execution_time'); // Store the limit
$update = G\fetch_url('http://chevereto.com/api/get/info/free');

View File

@ -289,7 +289,7 @@ function get_share_links($share_element) {
function include_peafowl_head() {
$peafowl_css = get_static_url(CHV_PATH_PEAFOWL . 'peafowl.css');
$opensans_css = get_static_url(CHV_PATH_PEAFOWL . 'fonts/opensans/opensans.css');
echo '<meta name="generator" content="Chevereto ' . CHV\get_chevereto_version() . '">' . "\n" .
echo '<meta name="generator" content="' . G_APP_NAME . ' ' . CHV\get_chevereto_version() . '">' . "\n" .
'<link rel="stylesheet" href="' . $peafowl_css . '">' . "\n" .
'<link rel="stylesheet" href="' . $opensans_css . '">' . "\n\n" .
'<script>document.documentElement.className += " js";(function(w,d,u){w.readyQ=[];w.bindReadyQ=[];function p(x,y){if(x=="ready"){w.bindReadyQ.push(y);}else{w.readyQ.push(x);}};var a={ready:p,bind:p};w.$=w.jQuery=function(f){if(f===d||f===u){return a}else{p(f)}}})(window,document);var devices=["phone","phablet","tablet","laptop","desktop","largescreen"];window_to_device=function(){for(var e=[480,768,992,1200,1880,2180],n=[],t="",d=document.documentElement.clientWidth||document.getElementsByTagName("body")[0].clientWidth||window.innerWidth,o=0;o<devices.length;++o)d>=e[o]&&n.push(devices[o]);0==n.length&&n.push(devices[0]),t=n[n.length-1];for(var o=0;o<devices.length;++o)document.documentElement.className=document.documentElement.className.replace(devices[o],""),o==devices.length-1&&(document.documentElement.className+=" "+t),document.documentElement.className=document.documentElement.className.replace(/\s+/g," ");if("laptop"==t||"desktop"==t){var c=document.getElementById("pop-box-mask");null!==c&&c.parentNode.removeChild(c)}},window_to_device(),window.onresize=window_to_device,$(document).ready(function(){PF.obj.devices=window.devices,PF.fn.window_to_device=window.window_to_device});</script>' . "\n\n";
@ -577,7 +577,7 @@ function chevereto_die($error_msg, $paragraph=NULL, $title=NULL) {
if(!is_array($error_msg) && G\check_value($error_msg)) $error_msg = array($error_msg);
if(is_null($paragraph)) {
$paragraph = "The system has encountered errors or missettings that must be fixed to allow proper Chevereto functionality. Chevereto won't run until the following issues are solved:";
$paragraph = "The system has encountered errors that must be fixed to allow proper Chevereto functionality. Chevereto won't work until the following issues are solved:";
}
$solution = "Need help or questions about this? Go to <a href='http://chevereto.com/support' target='_blank'>Chevereto support<a/>.";
$title = (!is_null($title)) ? $title : 'System error';
@ -929,7 +929,7 @@ function show_queue_img() {
}
function showPingPixel() {
if(is_null(CHV\getSetting('update_check_datetimegmt')) || G\datetime_add(CHV\getSetting('update_check_datetimegmt'), 'P1D') < G\datetimegmt()) {
if(CHV\getSetting('enable_automatic_updates_check') && (is_null(CHV\getSetting('update_check_datetimegmt')) || G\datetime_add(CHV\getSetting('update_check_datetimegmt'), 'P1D') < G\datetimegmt())) {
echo getPixel('ping');
}
}

View File

@ -32,23 +32,21 @@ function check_system_integrity() {
/*** Check server requirements ***/
// Try to fix the sessions in crap setups (OVH)
// Try to fix sessions in crap setups (OVH)
@ini_set('session.gc_divisor', 100);
@ini_set('session.gc_probability', true);
@ini_set('session.use_trans_sid', false);
@ini_set('session.use_only_cookies', true);
@ini_set('session.gc_probability', TRUE);
@ini_set('session.use_trans_sid', FALSE);
@ini_set('session.use_only_cookies', TRUE);
@ini_set('session.hash_bits_per_character', 4);
$missng_fn_tpl = '%n (<a href="http://php.net/manual/en/function.%u.php">%f</a>) function is disabled in this server. This function must be enabled in your PHP configuration (php.ini) and/or you must add this missing function.';
if(version_compare(PHP_VERSION, '5.4.0', '<'))
$install_errors[] = 'This server is currently running PHP version '.PHP_VERSION.' and Chevereto needs at least PHP 5.4.0 to run. You need to update PHP in this server.';
if(version_compare(PHP_VERSION, '5.5.0', '<'))
$install_errors[] = 'This server is currently running PHP version '.PHP_VERSION.' and Chevereto needs at least PHP 5.5.0 to run. You need to update PHP in this server.';
if(!extension_loaded('curl') && !function_exists('curl_init'))
$install_errors[] = 'Client URL library (<a href="http://curl.haxx.se/" target="_blank">cURL</a>) is not enabled in this server. cURL is needed to perform URL fetching.';
if(!function_exists('curl_exec'))
$install_errors[] = strtr($missng_fn_tpl, ['%n' => 'Curl exec', '%f' => 'curl_exec', '%u' => 'curl-exec']);
if(ini_get('allow_url_fopen') !== 1 && !function_exists('curl_init')) {
$install_errors[] = "cURL isn't installed and allow_url_fopen is disabled. Chevereto needs one of these to perform HTTP requests to remote servers.";
}
if(preg_match('/apache/i', $_SERVER['SERVER_SOFTWARE']) && function_exists('apache_get_modules') && !in_array('mod_rewrite', apache_get_modules())) {
$install_errors[] = 'Apache <a href="http://httpd.apache.org/docs/2.1/rewrite/rewrite_intro.html" target="_blank">mod_rewrite</a> is not enabled in this server. This must be enabled to run Chevereto.';

View File

@ -144,12 +144,6 @@ if(Settings::get('chevereto_version_installed')) {
// Language localization
(file_exists(G_APP_PATH_LIB . 'l10n.php')) ? require_once(G_APP_PATH_LIB . 'l10n.php') : die("Can't find app/lib/l10n.php");
// Process ping update
if(array_key_exists('ping', $_REQUEST) && $_REQUEST['r']) {
L10n::setLocale(Settings::get('default_language')); // Force system language
checkUpdates();
}
// Not installed
if(!Settings::get('chevereto_version_installed')) {
new G\Handler([
@ -161,10 +155,18 @@ if(!Settings::get('chevereto_version_installed')) {
]);
}
// Process ping update
if(Settings::get('enable_automatic_updates_check') && array_key_exists('ping', $_REQUEST) && $_REQUEST['r']) {
L10n::setLocale(Settings::get('default_language')); // Force system language
checkUpdates();
}
// Delete expired images
try {
if(method_exists('CHV\Image','deleteExpired')) {
try {
Image::deleteExpired();
} catch(Exception $e) {} // Silence
} catch(Exception $e) {}
}
// Translate logged user count labels
if(Login::isLoggedUser()) {
@ -174,13 +176,22 @@ if(Login::isLoggedUser()) {
}
// Handle banned IP address
$banned_ip = Ip_ban::getSingle();
if($banned_ip) {
if(method_exists('CHV\Ip_ban','getSingle')) {
$banned_ip = Ip_ban::getSingle();
if($banned_ip) {
if(G\is_url($banned_ip['message'])) {
G\redirect($banned_ip['message']);
} else {
die(empty($banned_ip['message']) ? _s('You have been forbidden to use this website.') : $banned_ip['message']);
}
}
}
// Handle invalid user accounts
if(method_exists('CHV\User','cleanup')) {
try {
User::cleanup();
} catch(Exception $e) {}
}
// Append any app loader hook (user own hooks)
@ -274,7 +285,7 @@ try {
$handler::setVar('header_logo_link', G\get_base_url());
$handler::setCond('admin', $is_admin);
$handler::setCond('maintenance', getSetting('maintenance') AND !Login::getUser()['is_admin']);
$handler::setCond('show_consent_screen', getSetting('enable_consent_screen') ? !(Login::getUser() OR isset($_SESSION['agree-consent']) OR isset($_COOKIE['AGREE_CONSENT'])) : FALSE);
$handler::setCond('show_consent_screen', $base !== 'api' && (getSetting('enable_consent_screen') ? !(Login::getUser() OR isset($_SESSION['agree-consent']) OR isset($_COOKIE['AGREE_CONSENT'])) : FALSE));
$handler::setCond('captcha_needed', getSetting('recaptcha') AND getSetting('recaptcha_threshold') == 0);
$handler::setCond('show_header', !($handler::getCond('maintenance') OR $handler::getCond('show_consent_screen')));
$handler::setCond('show_notifications', FALSE);
@ -289,9 +300,9 @@ try {
$handler::setVar('consent_accept_url', G\get_current_url() . (parse_url(G\get_current_url(), PHP_URL_QUERY) ? '&' : '/?') . 'agree-consent');
}
// reCaptcha thing (only non logged users)
if(!Login::getUser()) {
$failed_access_requests = Requestlog::getCounts(['login', 'signup'], 'fail');
// reCaptcha thing (only non logged users)
if(getSetting('recaptcha') && $failed_access_requests['day'] > getSetting('recaptcha_threshold')) {
$handler::setCond('captcha_needed', TRUE);
}

View File

@ -38,10 +38,6 @@ $route = function($handler) {
G\redirect($logged_user['url']);
}
break;
case 'awaiting-confirmation':
if(!$logged_user or $logged_user['status'] !== 'awaiting-confirmation') {
}
break;
}
// reCaptcha thing

View File

@ -123,7 +123,7 @@ $route = function($handler) {
],
'chv_free' => [
'label' => 'Get more',
'content' => '<a href="https://chevereto.com/pricing" target="_blank">Upgrade</a> to contribute with Chevereto development and to get more <a href="https://chevereto.com/features" target="_blank">features</a>',
'content' => '<a href="https://chevereto.com/pricing" target="_blank">Upgrade</a> to contribute with Chevereto development and to get more <a href="https://chevereto.com/features" target="_blank">features</a> and support.',
],
'g_version' => [
'label' => 'G\\',
@ -169,8 +169,27 @@ $route = function($handler) {
'label' => _s('Memory limit'),
'content' => G\format_bytes(G\get_ini_bytes(ini_get('memory_limit')))
],
'links' => [
'label' => _s('Links'),
],
];
$chevereto_urls = [
_s('Documentation') => 'https://chevereto.com/docs',
_s('Changelog') => 'https://chevereto.com/changelog',
_s('Request new features') => 'https://chevereto.com/request-new-features',
_s('Bug tracking') => 'https://chevereto.com/bug-tracking',
_s('Blog') => 'https://chevereto.com/blog',
_s('Community') => 'https://chevereto.com/community',
'GitHub' => 'https://github.com/Chevereto',
];
$chevereto_links = [];
foreach($chevereto_urls as $k => $v) {
$chevereto_links[] = '<a href="'.$v.'" target="_blank">'.$k.'</a>';
}
$system_values['links']['content'] = implode(' ', $chevereto_links);
$handler::setVar('system_values', $system_values);
$handler::setVar('totals', $totals);
$handler::setVar('totals_display', $totals_display);
@ -229,6 +248,12 @@ $route = function($handler) {
}
}
// Reject non-existing settings sections
if(!empty($handler->request[1]) && !array_key_exists($handler->request[1], $settings_sections)) {
return $handler->issue404();
}
$handler::setVar('settings_menu', $settings_sections);
//$handler::setVar('tabs', $settings_sections);
@ -443,6 +468,11 @@ $route = function($handler) {
'validate' => is_numeric($_POST['listing_items_per_page']) and $_POST['listing_items_per_page'] > 0,
'error_msg' => _s('Invalid value')
],
'upload_threads' =>
[
'validate' => filter_var($_POST['upload_threads'], FILTER_VALIDATE_INT) && $_POST['upload_threads'] > 0 && $_POST['upload_threads'] <= 5,
'error_msg' => _s('Invalid value')
],
'upload_storage_mode' =>
[
'validate' => in_array($_POST['upload_storage_mode'], ['datefolder', 'direct']),
@ -455,27 +485,27 @@ $route = function($handler) {
],
'upload_thumb_width'=>
[
'validate' => is_numeric($_POST['upload_thumb_width']),
'validate' => filter_var($_POST['upload_thumb_width'], FILTER_VALIDATE_INT),
'error_msg' => _s('Invalid thumb width')
],
'upload_thumb_height'=>
[
'validate' => is_numeric($_POST['upload_thumb_height']),
'validate' => filter_var($_POST['upload_thumb_height'], FILTER_VALIDATE_INT),
'error_msg' => _s('Invalid thumb height')
],
'upload_medium_size'=>
[
'validate' => is_numeric($_POST['upload_medium_size']),
'validate' => filter_var($_POST['upload_medium_size'], FILTER_VALIDATE_INT),
'error_msg' => _s('Invalid medium size')
],
'watermark_percentage' =>
[
'validate' => is_numeric($_POST['watermark_percentage']) and (1 <= $_POST['watermark_percentage'] && $_POST['watermark_percentage'] <= 100),
'validate' => filter_var($_POST['watermark_percentage'], FILTER_VALIDATE_INT) and (1 <= $_POST['watermark_percentage'] && $_POST['watermark_percentage'] <= 100),
'error_msg' => _s('Invalid watermark percentage')
],
'watermark_opacity' =>
[
'validate' => is_numeric($_POST['watermark_opacity']) and (1 <= $_POST['watermark_opacity'] && $_POST['watermark_opacity'] <= 100),
'validate' => filter_var($_POST['watermark_opacity'], FILTER_VALIDATE_INT) and (1 <= $_POST['watermark_opacity'] && $_POST['watermark_opacity'] <= 100),
'error_msg' => _s('Invalid watermark opacity')
],
'theme' =>
@ -485,7 +515,7 @@ $route = function($handler) {
],
'theme_logo_height' =>
[
'validate' => G\check_value($_POST['theme_logo_height']) ? is_numeric($_POST['theme_logo_height']) : true,
'validate' => G\check_value($_POST['theme_logo_height']) ? filter_var($_POST['theme_logo_height'], FILTER_VALIDATE_INT) : true,
'error_msg' => _s('Invalid value')
],
'theme_tone' =>
@ -540,7 +570,7 @@ $route = function($handler) {
],
'website_mode_personal_uid' =>
[
'validate' => $_POST['website_mode'] == 'personal' ? is_numeric($_POST['website_mode_personal_uid']) : TRUE,
'validate' => $_POST['website_mode'] == 'personal' ? filter_var($_POST['website_mode_personal_uid'], FILTER_VALIDATE_INT) : TRUE,
'error_msg' => _s('Invalid personal mode user ID')
],
'website_mode_personal_routing' =>
@ -650,11 +680,6 @@ $route = function($handler) {
$validations['route_album'] = $validations['route_image'];
}
$bool_validations = ['auto_language', 'guest_uploads', 'error_reporting', 'maintenance', 'cloudflare', 'recaptcha', 'cdn'];
foreach($bool_validations as $v) {
$validations[$v] = ['validate' => in_array($_POST[$v], [0,1]) ? true : false];
}
// Validate image path
if($_POST['upload_image_path']) {
$safe_upload_image_path = rtrim(G\sanitize_relative_path($_POST['upload_image_path']), '/');
@ -730,8 +755,20 @@ $route = function($handler) {
// 1. No pueden mappear una ruta ya existente, excepto self (no puden mapear /dashboard, pero si /image)
// 2. No pueden mapear a un username
// Handle disabled image formats
if($_POST['image_format_enable'] && is_array($_POST['image_format_enable'])) {
// Validate each entry
$image_format_enable = [];
foreach($_POST['image_format_enable'] as $v) {
if(in_array($v, CHV\Upload::getAvailableImageFormats())) {
$image_format_enable[] = $v;
}
}
$_POST['upload_enabled_image_formats'] = implode(',', $image_format_enable);
}
// Handle disabled languages
if($_POST['languages_enable']) {
if($_POST['languages_enable'] && is_array($_POST['image_format_enable'])) {
// Push default language
if(!in_array($_POST['default_language'], $_POST['languages_enable'])) {

View File

@ -56,9 +56,9 @@ $route = function($handler) {
return $handler->issue404();
}
// Test remote image
// Test local images
if($image['file_resource']['type'] == 'path') {
if(!$image['file_resource']['chain']['image'] || !file_exists($image['file_resource']['chain']['image'])) {
//CHV\Image::delete($id);
return $handler->issue404();
}
// Update is_animated flag
@ -66,6 +66,13 @@ $route = function($handler) {
CHV\Image::update($id, ['is_animated' => 1]);
$image['is_animated'] = 1;
}
}
/*
Note: Remote image testing was removed because of the HUGE number of websites running external containers unaccesible via HTTP.
Remote image test works only if the website can fetch the image URI headers.
Check Chevereto < 3.8.4 for the old remote image tester code
*/
$is_owner = $image['user']['id'] !== NULL ? ($image['user']['id'] == $logged_user['id']) : false;

View File

@ -43,9 +43,8 @@ $route = function($handler) {
G\redirect(CHV\User::getUrl($logged_user));
}
// Request log
// Failed access requests filter
$failed_access_requests = $handler::getVar('failed_access_requests');
if(CHV\is_max_invalid_request($failed_access_requests['day'])) {
G\set_status_header(403);
$handler->template = 'request-denied';
@ -56,7 +55,7 @@ $route = function($handler) {
$SAFE_POST = $handler::getVar('safe_post');
// Conds
$is_error = false;
$is_error = FALSE;
// Vars
$input_errors = NULL;
@ -69,7 +68,7 @@ $route = function($handler) {
if($_POST) {
$captcha = CHV\recaptcha_check();
if(!$captcha->is_valid) {
$is_error = true;
$is_error = TRUE;
$error_message = _s("The reCAPTCHA wasn't entered correctly");
}
}
@ -77,7 +76,7 @@ $route = function($handler) {
$handler::setCond('show_resend_activation', false);
if($_POST and !$is_error and !$_SESSION['signup']) {
if($_POST && !$is_error && !$_SESSION['signup']) {
$__post = [];
$__safe_post = [];
@ -166,13 +165,24 @@ $route = function($handler) {
];
// Ready to go, insert the new user
try {
$inserted_user = CHV\User::insert($user_array);
} catch(Exception $e) {
if($e->getCode() == 666) { // Flood detected!
G\set_status_header(403);
$handler->template = 'request-denied';
return;
} else {
throw new Exception($e);
}
}
if($inserted_user) {
$insert_password = CHV\Login::addPassword($inserted_user, $_POST['password']);
}
if(!$inserted_user or !$insert_password) {
if(!$inserted_user || !$insert_password) {
throw new Exception("Can't insert user to the DB", 400);
} else {
if(CHV\getSetting('require_user_email_confirmation')) {
@ -236,10 +246,10 @@ $route = function($handler) {
}
if($is_error) {
CHV\Requestlog::insert(array('type' => 'signup', 'result' => 'fail'));
CHV\Requestlog::insert(['type' => 'signup', 'result' => 'fail']);
$error_message = _s('Check the errors in the form to continue.');
if(CHV\getSettings()['recaptcha'] and CHV\must_use_recaptcha($failed_access_requests['day'] + 1)) {
$captcha_needed = true;
if(CHV\getSettings()['recaptcha'] && CHV\must_use_recaptcha($failed_access_requests['day'] + 1)) {
$captcha_needed = TRUE;
}
}
@ -248,7 +258,7 @@ $route = function($handler) {
$handler::setCond('error', $is_error);
$handler::setCond('captcha_needed', $captcha_needed);
if($captcha_needed and !$handler::getVar('recaptcha_html')) {
if($captcha_needed && !$handler::getVar('recaptcha_html')) {
$handler::setVar('recaptcha_html', CHV\Render\get_recaptcha_html('clean'));
}

View File

@ -1,9 +1,7 @@
<?php if(!defined('access') or !access) die('This file cannot be directly accessed.'); ?>
<div id="powered-by" class="footer">Powered by <a href="http://chevereto.com">Chevereto image hosting</a></div>
<?php if(!is_maintenance()) { ?>
<?php G\Render\include_theme_file('snippets/embed_tpl'); ?>
<?php } ?>
<?php if(!is_maintenance()) { G\Render\include_theme_file('snippets/embed_tpl'); } ?>
<?php
if(is_upload_allowed()) {

View File

@ -1,5 +1,5 @@
<?php if(!defined('access') or !access) die('This file cannot be directly accessed.'); ?><!DOCTYPE HTML>
<html <?php echo CHV\Render\get_html_tags(); ?>>
<?php if(!defined('access') or !access) die('This file cannot be directly accessed.');?><!DOCTYPE HTML>
<html <?php echo CHV\Render\get_html_tags(); ?> prefix="og: http://ogp.me/ns#">
<head>
<meta charset="utf-8">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
@ -24,6 +24,8 @@
<?php
if(!is_maintenance()) { G\Render\include_theme_file('snippets/embed'); }
if(CHV\getSetting('theme_logo_height') > 0) {
$logo_height = CHV\getSetting('theme_logo_height');
echo '<style type="text/css">.top-bar-logo, .top-bar-logo img { height: '.CHV\getSetting('theme_logo_height').'px; } .top-bar-logo { margin-top: -'.(CHV\getSetting('theme_logo_height')/2).'px; } </style>';
@ -41,6 +43,7 @@ $open_graph = [
switch(true) {
case function_exists('get_image') and G\is_route('image'):
$open_graph_extend = [
'type' => 'article',
'title' => get_pre_doctitle(),
'description' => get_image()['description'],
'image' => get_image()['url'],
@ -72,7 +75,7 @@ if($open_graph_extend) {
}
foreach($open_graph as $k => $v) {
if(!$v) continue;
echo '<meta property="og:'.$k.'" content="'.G\safe_html($v, ENT_COMPAT).'">' . "\n";
echo '<meta property="og:'.$k.'" content="'.G\safe_html($v, ENT_COMPAT).'" />' . "\n";
}
// Set twitter card
@ -243,7 +246,7 @@ foreach($twitter_card as $k => $v) {
<span class="top-btn-text"><span class="icon icon-notification color-red"></span><span class="btn-text phone-hide phablet-hide"><?php _se('Notices (%s)', count(get_system_notices())); ?></span></span>
<div class="pop-box anchor-center c8 arrow-box arrow-box-top anchor-center">
<div class="pop-box-inner padding-20">
<ul class="list-style-type-disc list-style-position-inside">
<ul class="list-style-type-decimal list-style-position-inside">
<?php foreach(get_system_notices() as $notice) { ?>
<li><?php echo $notice; ?></li>
<?php } ?>

View File

@ -43,7 +43,7 @@
</div>
</div>
<input id="anywhere-upload-input" data-action="anywhere-upload-input"<?php if(!CHV\getSetting('guest_uploads')) { ?> data-login-needed="true"<?php } ?> class="hidden-visibility" type="file" accept="image/*" multiple>
<input id="anywhere-upload-input" data-action="anywhere-upload-input"<?php if(!CHV\getSetting('guest_uploads')) { ?> data-login-needed="true"<?php } ?> class="hidden-visibility" type="file" accept="<?php echo '.' . implode(',.', CHV\Upload::getEnabledImageFormats()); ?>" multiple>
<input id="anywhere-upload-input-camera" data-action="anywhere-upload-input"<?php if(!CHV\getSetting('guest_uploads')) { ?> data-login-needed="true"<?php } ?> class="hidden-visibility" type="file" capture="camera" accept="image/*">
<ul id="anywhere-upload-queue" class="upload-box-queue content-width soft-hidden" data-group="upload-queue"></ul>
@ -86,7 +86,7 @@
<div data-group="upload-result" data-result="error" class="soft-hidden margin-top-10 text-align-center upload-box-status-text"><?php _se('Check the <a data-modal="simple" data-target="failed-upload-result">error report</a> for more information.'); ?></div>
</div>
<div class="upload-box-allowed-files position-absolute"><span class="phone-hide">jpg png bmp gif</span> <span><?php _se('max'); ?> <?php echo G\format_bytes(G\get_bytes(CHV\getSetting('upload_max_filesize_mb').'MB')); ?></span></div>
<div class="upload-box-allowed-files position-absolute"><span class="phone-hide"><?php echo str_replace(',', ' ', strtoupper(CHV\getSetting('upload_enabled_image_formats'))); ?></span> <span><?php _se('max'); ?> <?php echo G\format_bytes(G\get_bytes(CHV\getSetting('upload_max_filesize_mb').'MB')); ?></span></div>
<div class="upload-box-close position-absolute">
<a data-action="close-upload" data-button="close-cancel"><span class="btn-icon icon-close"></span><span class="btn-text"><?php _se('close'); ?></span></a>
<a data-action="cancel-upload" data-button="close-cancel" class="soft-hidden"><span class="btn-icon icon-close"></span><span class="btn-text"><?php _se('cancel'); ?></span></a>

View File

@ -0,0 +1,94 @@
<?php if(!defined('access') or !access) die('This file cannot be directly accessed.');
global $embed_tpl;
$embed_tpl = [
'links' => [
'label' => _s('Links'),
'options' => [
'viewer-links' => [
'label' => _s('Viewer links'),
'template' => '%URL_VIEWER%',
'size' => 'viewer'
],
'direct-links' => [
'label' => _s('Direct links'),
'template' => '%URL%',
'size' => 'full'
]
]
],
'html-codes' => [
'label' => _s('HTML Codes'),
'options' => [
'html-embed' => [
'label' => _s('HTML image'),
'template' => '<img src="%URL%" alt="%FILENAME%" border="0">',
'size' => 'full'
],
'html-embed-full' => [
'label' => _s('HTML full linked'),
'template' => '<a href="%URL_VIEWER%"><img src="%URL%" alt="%FILENAME%" border="0"></a>',
'size' => 'full'
],
'html-embed-medium' => [
'label' => _s('HTML medium linked'),
'template' => '<a href="%URL_VIEWER%"><img src="%MEDIUM_URL%" alt="%MEDIUM_FILENAME%" border="0"></a>',
'size' => 'medium'
],
'html-embed-thumbnail' => [
'label' => _s('HTML thumbnail linked'),
'template' => '<a href="%URL_VIEWER%"><img src="%THUMB_URL%" alt="%THUMB_FILENAME%" border="0"></a>',
'size' => 'thumb'
]
]
],
'bbcodes' => [
'label' => _s('BBCodes'),
'options' => [
'bbcode-embed' => [
'label' => _s('BBCode full'),
'template' => '[img]%URL%[/img]',
'size' => 'full'
],
'bbcode-embed-full' => [
'label' => _s('BBCode full linked'),
'template' => '[url=%URL_VIEWER%][img]%URL%[/img][/url]',
'size' => 'full'
],
'bbcode-embed-medium' => [
'label' => _s('BBCode medium linked'),
'template' => '[url=%URL_VIEWER%][img]%MEDIUM_URL%[/img][/url]',
'size' => 'medium'
],
'bbcode-embed-thumbnail' => [
'label' => _s('BBCode thumbnail linked'),
'template' => '[url=%URL_VIEWER%][img]%THUMB_URL%[/img][/url]',
'size' => 'thumb'
]
]
],
'markdown' => [
'label' => 'Markdown',
'options' => [
'markdown-embed' => [
'label' => _s('Markdown full'),
'template' => '![%FILENAME%](%URL%)',
'size' => 'full'
],
'markdown-embed-full' => [
'label' => _s('Markdown full linked'),
'template' => '[![%FILENAME%](%URL%)](%URL_VIEWER%)',
'size' => 'full'
],
'markdown-embed-medium' => [
'label' => _s('Markdown medium linked'),
'template' => '[![%MEDIUM_FILENAME%](%MEDIUM_URL%)](%URL_VIEWER%)',
'size' => 'medium'
],
'markdown-embed-thumbnail' => [
'label' => _s('Markdown thumbnail linked'),
'template' => '[![%THUMB_FILENAME%](%THUMB_URL%)](%URL_VIEWER%)',
'size' => 'thumb'
]
]
]
];

View File

@ -1,99 +1,4 @@
<?php if(!defined('access') or !access) die('This file cannot be directly accessed.'); ?>
<?php
global $embed_tpl;
$embed_tpl = [
'links' => [
'label' => _s('Links'),
'options' => [
'viewer-links' => [
'label' => _s('Viewer links'),
'template' => '%URL_VIEWER%',
'size' => 'viewer'
],
'direct-links' => [
'label' => _s('Direct links'),
'template' => '%URL%',
'size' => 'full'
]
]
],
'html-codes' => [
'label' => _s('HTML Codes'),
'options' => [
'html-embed' => [
'label' => _s('HTML image'),
'template' => '<img src="%URL%" alt="%FILENAME%" border="0">',
'size' => 'full'
],
'html-embed-full' => [
'label' => _s('HTML full linked'),
'template' => '<a href="%URL_VIEWER%"><img src="%URL%" alt="%FILENAME%" border="0"></a>',
'size' => 'full'
],
'html-embed-medium' => [
'label' => _s('HTML medium linked'),
'template' => '<a href="%URL_VIEWER%"><img src="%MEDIUM_URL%" alt="%MEDIUM_FILENAME%" border="0"></a>',
'size' => 'medium'
],
'html-embed-thumbnail' => [
'label' => _s('HTML thumbnail linked'),
'template' => '<a href="%URL_VIEWER%"><img src="%THUMB_URL%" alt="%THUMB_FILENAME%" border="0"></a>',
'size' => 'thumb'
]
]
],
'bbcodes' => [
'label' => _s('BBCodes'),
'options' => [
'bbcode-embed' => [
'label' => _s('BBCode full'),
'template' => '[img]%URL%[/img]',
'size' => 'full'
],
'bbcode-embed-full' => [
'label' => _s('BBCode full linked'),
'template' => '[url=%URL_VIEWER%][img]%URL%[/img][/url]',
'size' => 'full'
],
'bbcode-embed-medium' => [
'label' => _s('BBCode medium linked'),
'template' => '[url=%URL_VIEWER%][img]%MEDIUM_URL%[/img][/url]',
'size' => 'medium'
],
'bbcode-embed-thumbnail' => [
'label' => _s('BBCode thumbnail linked'),
'template' => '[url=%URL_VIEWER%][img]%THUMB_URL%[/img][/url]',
'size' => 'thumb'
]
]
],
'markdown' => [
'label' => 'Markdown',
'options' => [
'markdown-embed' => [
'label' => _s('Markdown full'),
'template' => '![%FILENAME%](%URL%)',
'size' => 'full'
],
'markdown-embed-full' => [
'label' => _s('Markdown full linked'),
'template' => '[![%FILENAME%](%URL%)](%URL_VIEWER%)',
'size' => 'full'
],
'markdown-embed-medium' => [
'label' => _s('Markdown medium linked'),
'template' => '[![%MEDIUM_FILENAME%](%MEDIUM_URL%)](%URL_VIEWER%)',
'size' => 'medium'
],
'markdown-embed-thumbnail' => [
'label' => _s('Markdown thumbnail linked'),
'template' => '[![%THUMB_FILENAME%](%THUMB_URL%)](%URL_VIEWER%)',
'size' => 'thumb'
]
]
]
];
?>
<script>
$(document).ready(function() {
if(typeof CHV == "undefined") {
@ -103,7 +8,7 @@ $embed_tpl = [
CHV.obj.embed_tpl = {};
}
}
CHV.obj.embed_tpl = <?php echo json_encode($embed_tpl); ?>;
CHV.obj.embed_tpl = <?php $embed_tpl = G\get_global('embed_tpl'); echo json_encode($embed_tpl); ?>;
});
</script>
<div data-modal="form-embed-codes" class="hidden">

View File

@ -42,7 +42,9 @@ CHV.obj.config = {
right_click: <?php echo json_encode(CHV\getSetting('theme_image_right_click')); ?>,
},
upload: {
redirect_single_upload: <?php echo json_encode(CHV\getSetting('enable_redirect_single_upload')); ?>
redirect_single_upload: <?php echo json_encode(CHV\getSetting('enable_redirect_single_upload')); ?>,
threads: <?php echo json_encode(CHV\getSetting('upload_threads')); ?>,
image_types: <?php echo json_encode(CHV\Upload::getEnabledImageFormats()); ?>
},
user: {
avatar_max_filesize: "<?php echo CHV\getSetting('user_image_avatar_max_filesize_mb') . ' MB'; ?>",

View File

@ -16,7 +16,7 @@ foreach($tabs as $tab) {
$echo = [
'<li class="' . (isset($tab['class']) ? $tab['class'] : '') . ' ' .($tab["current"] ? 'current' : '') . '">',
'<a ',
$tab['id'] ? ('id="' . $tab['id'] . '-link" data-tab="' . $tab["id"] . '"' ) : '',
$tab['id'] ? ('id="' . $tab['id'] . '-link" data-tab="' . $tab["id"] . '" ' ) : '',
'href="' . $tab['url'] . '">',
$tab["label"],
'</a></li>'."\n"

View File

@ -901,6 +901,7 @@ body.split #home-cover {
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
overflow: auto;
}
#home-cover-content p, #home-cover-content h1 {
text-shadow: 1px 1px 2px rgba(0,0,0,.25)
@ -930,7 +931,7 @@ body.split #home-cover {
font-weight: 100;
}
#home-cover-content .home-buttons {
margin: 30px 0 0 0;
margin: 30px 0 20px;
}
.home-buttons {

File diff suppressed because one or more lines are too long

View File

@ -125,6 +125,12 @@
echo '<div class="input-below"><span class="icon icon-info color-red"></span> ' . _s('This setting is always diabled when using personal website mode.') . '</div>';
}
}
function read_the_docs($args=[]) {
return _s('Learn more about %s at our %d.', [
'%s' => $args['%s'],
'%d' => '<a href="https://chevereto.com/docs/'.$args['%k'].'" target="_blank">'._s('documentation').'</a>'
]);
}
function free_version_waring($wrap=TRUE) {
$message = _s("This functionality is not part of Chevereto Free. %s to obtain this feature.", ['%s' => '<a href="https://chevereto.com/pricing" target="_blank">' . _s('Upgrade to paid version') . '</a>']);
echo ($wrap ? ('<div class="input-below">' . $message . '</div>') : $message);
@ -608,6 +614,7 @@
if(get_pages() and count(get_pages()) > 0) {
$auth_token = G\Handler::getAuthToken();
?>
<p><?php echo read_the_docs(['%s' => _s('pages'), '%k' => 'pages']); ?></p>
<ul data-content="dashboard-categories-list" class="tabbed-content-list table-li-hover table-li margin-top-20 margin-bottom-20">
<li class="table-li-header phone-hide">
<span class="c2 display-table-cell padding-right-10"><?php echo 'ID'; ?></span>
@ -645,6 +652,23 @@
<?php } // pages ?>
<?php if(get_settings()['key'] == 'image-upload') { ?>
<div class="input-label">
<label>Enabled image formats</label>
<div class="checkbox-label">
<ul class="c20 phablet-c1">
<?php
foreach(CHV\Upload::getAvailableImageFormats() as $k) {
echo '<li class="c5 display-inline-block"><label class="display-block" for="image_format_enable['.$k.']"> <input type="checkbox" name="image_format_enable[]" id="image_format_enable['.$k.']" value="'.$k.'"'.(in_array($k, CHV\Upload::getEnabledImageFormats()) ? ' checked' : NULL).'>'.strtoupper($k).'</label></li>';
}
?>
</ul>
<div class="input-below input-warning red-warning"><?php echo get_input_errors()['upload_enabled_image_formats']; ?></div>
<p class="margin-top-20"><?php _se("Unchecked image formats won't be allowed to be uploaded."); ?></p>
</div>
</div>
<hr class="line-separator"></hr>
<div class="input-label">
<label for="enable_uploads"><?php _se('Enable uploads'); ?></label>
<div class="c5 phablet-c1"><select type="text" name="enable_uploads" id="enable_uploads" class="text-input">
@ -667,6 +691,13 @@
<hr class="line-separator"></hr>
<div class="input-label">
<label for="upload_threads">Upload threads</label>
<div class="c2"><input type="number" min="1" max="5" pattern="\d+" name="upload_threads" id="upload_threads" class="text-input" value="<?php echo CHV\Settings::get('upload_threads'); ?>" placeholder="2" required></div>
<div class="input-below input-warning red-warning"><?php echo get_input_errors()['upload_threads']; ?></div>
<div class="input-below"><?php _se('Number of simultaneous upload threads (parallel uploads)'); ?></div>
</div>
<div class="input-label">
<label for="enable_redirect_single_upload"><?php _se('Redirect on single upload'); ?></label>
<div class="c5 phablet-c1"><select type="text" name="enable_redirect_single_upload" id="enable_redirect_single_upload" class="text-input">
@ -1251,8 +1282,9 @@
<?php } ?>
<?php if(get_settings()['key'] == 'theme') { ?>
<p><?php echo _se('Put your themes in the %s folder', G_APP_PATH_THEMES); ?></p>
<div class="input-label c5 phablet-c1">
<p><?php echo read_the_docs(['%s' => _s('theme editing'), '%k' => 'theme']); ?></p>
<hr class="line-separator"></hr>
<div class="input-label">
<label for="theme"><?php _se("Theme"); ?></label>
<?php
$themes = [];
@ -1262,13 +1294,16 @@
}
}
?>
<div class="c5 phablet-c1">
<select type="text" name="theme" id="theme" class="text-input">
<?php
echo CHV\Render\get_select_options_html($themes, CHV\Settings::get('theme'));
?>
</select>
</div>
<div class="input-below"><?php echo _se('Put your themes in the %s folder', G_APP_PATH_THEMES); ?></div>
</div>
<hr class="line-separator"></hr>
<div class="input-label">
<label for="theme_tone"><?php _se('Tone'); ?></label>
<div class="c5 phablet-c1"><select type="text" name="theme_tone" id="theme_tone" class="text-input">
@ -1627,6 +1662,27 @@
<?php } ?>
<?php if(get_settings()['key'] == 'system') { ?>
<div class="input-label">
<label for="enable_automatic_updates_check"><?php _se('Automatic updates check'); ?></label>
<div class="c5 phablet-c1"><select type="text" name="enable_automatic_updates_check" id="enable_automatic_updates_check" class="text-input">
<?php
echo CHV\Render\get_select_options_html([1 => _s('Enabled'), 0 => _s('Disabled')], CHV\Settings::get('enable_automatic_updates_check'));
?>
</select></div>
<div class="input-below input-warning red-warning"><?php echo get_input_errors()['enable_automatic_updates_check']; ?></div>
<div class="input-below"><?php _se('When enabled the system will automatically check for new updates.'); ?></div>
</div>
<div class="input-label">
<label for="update_check_display_notification"><?php _se('Display available updates notification'); ?></label>
<div class="c5 phablet-c1"><select type="text" name="update_check_display_notification" id="update_check_display_notification" class="text-input">
<?php
echo CHV\Render\get_select_options_html([0 => _s('Disabled'), 1 => _s('Enabled')], CHV\Settings::get('update_check_display_notification'));
?>
</select></div>
<div class="input-below input-warning red-warning"><?php echo get_input_errors()['update_check_display_notification']; ?></div>
<div class="input-below"><?php _se("Enable this to show a notice on top warning you about new available system updates."); ?></div>
</div>
<hr class="line-separator"></hr>
<div class="input-label">
<label for="minify_enable"><?php _se('Minify code'); ?></label>
<div class="c5 phablet-c1"><select type="text" name="minify_enable" id="minify_enable" class="text-input">
@ -1645,15 +1701,7 @@
</select></div>
<div class="input-below"><?php _se("When enabled the website will show a maintenance message. This setting doesn't affect administrators."); ?></div>
</div>
<div class="input-label">
<label for="update_check_display_notification"><?php _se('Display available updates notification'); ?></label>
<div class="c5 phablet-c1"><select type="text" name="update_check_display_notification" id="update_check_display_notification" class="text-input">
<?php
echo CHV\Render\get_select_options_html([0 => _s('Disabled'), 1 => _s('Enabled')], CHV\Settings::get('update_check_display_notification'));
?>
</select></div>
<div class="input-below"><?php _se("Enable this to show a notice on top warning you about new available system updates."); ?></div>
</div>
<hr class="line-separator"></hr>
<div class="input-label">
<label for="crypt_salt"><?php _se('Crypt salt'); ?></label>
<div class="c5 phablet-c1"><input type="text" name="crypt_salt" id="crypt_salt" class="text-input" value="<?php echo CHV\Settings::get('crypt_salt'); ?>" disabled></div>
@ -1702,6 +1750,10 @@
<?php } ?>
<?php if(get_settings()['key'] == 'languages') { ?>
<div class="input-label">
<label><?php _se('Custom language strings'); ?></label>
<p><?php echo read_the_docs(['%s' => _s('language strings'), '%k' => 'language-strings']); ?></p>
</div>
<div class="input-label">
<label for="default_language"><?php _se('Default language'); ?></label>
<div class="c5 phablet-c1"><select type="text" name="default_language" id="default_language" class="text-input">
@ -1847,7 +1899,7 @@
echo CHV\Render\get_select_options_html([1 => _s('Enabled'), 0 => _s('Disabled')], get_safe_post() ? get_safe_post()['cdn'] : CHV\Settings::get('cdn'));
?>
</select></div>
<div class="input-below"><?php _se("CDN allows you to offload static content to several edge servers making your website faster. If you don't have a CDN provider you should try %s.", '<a href="https://chevereto.com/go/maxcdn" target="_blank">MaxCDN</a>'); ?></div>
<div class="input-below"><?php echo read_the_docs(['%s' => 'CDN', '%k' => 'cdn']); ?></div>
</div>
<div id="cdn-combo" class="c9 phablet-c1">
<div data-combo-value="1" class="switch-combo<?php if(!(get_safe_post() ? get_safe_post()['cdn'] : CHV\Settings::get('cdn'))) echo ' soft-hidden'; ?>">
@ -1911,6 +1963,7 @@
echo CHV\Render\get_select_options_html([1 => _s('Enabled'), 0 => _s('Disabled')], CHV\Settings::get('cloudflare'));
?>
</select></div>
<div class="input-below"><?php echo read_the_docs(['%s' => 'CloudFlare', '%k' => 'cloudflare']); ?></div>
</div>
<?php } ?>

View File

@ -29,8 +29,6 @@
</div>
</div>
<?php CHV\Render\show_banner('home_after_cover'); ?>
<?php if (CHV\Settings::get('homepage_style') == 'split') { ?>
<div class="content-width">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 KiB

After

Width:  |  Height:  |  Size: 259 KiB

View File

@ -18,7 +18,7 @@ namespace G;
if(!defined('access') or !access) die("This file cannot be directly accessed.");
define('G_VERSION', '1.0.29');
define('G_VERSION', '1.0.31');
// Error reporting setup
@ini_set('log_errors', TRUE);
@ -99,7 +99,7 @@ if(file_exists(G_APP_PATH . 'app.php')) {
}
// Set the DB constants
foreach(['host', 'port', 'name', 'user', 'pass', 'driver'] as $k) {
foreach(['host', 'port', 'name', 'user', 'pass', 'driver', 'pdo_attrs'] as $k) {
define('G_APP_DB_' . strtoupper($k), isset($settings['db_' . $k]) ? $settings['db_' . $k] : NULL);
}

View File

@ -33,7 +33,7 @@ class DB {
private $pass = G_APP_DB_PASS;
private $driver = G_APP_DB_DRIVER;
private $pdo_attrs;
private $pdo_attrs = G_APP_DB_PDO_ATTRS;
static $dbh;
public $query;
@ -51,23 +51,15 @@ class DB {
return TRUE;
}
if(empty($conn)) {
// Handle default conn values (from settings)
foreach(['host', 'port', 'name', 'user', 'pass', 'driver'] as $k) {
$define = 'G_APP_DB_' . strtoupper($k);
$this->{$k} = defined($define) ? constant($define) : NULL;
};
} else {
if(!empty($conn)) {
// Inject connection info
$this->host = $conn['host'];
$this->user = $conn['user'];
$this->name = $conn['name'];
$this->pass = $conn['pass'];
$this->port = $conn['port'];
$this->driver = $conn['driver'];
foreach(['host', 'user', 'name', 'pass', 'port', 'driver'] as $k) {
$this->{$k} = $conn[$k];
}
}
if(!empty($pdo_attrs)) {
$this->pdo_attrs = $pdo_attrs;
}
$pdo_connect = $this->driver . ':host=' . $this->host . ';dbname=' . $this->name;
if($this->port) {
@ -470,24 +462,28 @@ class DB {
/**
* Update target numecic table row(s) with and increment (positive or negative)
* Returns the number of affected rows or false
* Note: this should add a BASE value (like "0" to avoid negative values if set)
* Note: Minimum value to be set is zero, no negative values here
*/
public static function increment($table, $values, $wheres, $clause='AND') {
if(!is_array($values)) {
throw new DBException('Expecting array values, '.gettype($values).' given in '. __METHOD__, 100);
foreach(['values', 'wheres'] as $k) {
if(!is_array(${$k})) {
throw new DBException('Expecting array values, '.gettype(${$k}).' given in '. __METHOD__, 100);
}
if(!is_array($wheres)) {
throw new DBException('Expecting array values, '.gettype($wheres).' given in '. __METHOD__, 100);
}
$table = DB::getTable($table);
$query = 'UPDATE `'.$table.'` SET ';
foreach($values as $k => $v) {
if(preg_match('/^([+-]{1})\s*([\d]+)$/', $v, $matches)) {
$query .= '`' . $k . '`=`' . $k . '`' . $matches[1] . $matches[2] . ',';
if(preg_match('/^([+-]{1})\s*([\d]+)$/', $v, $matches)) { // 1-> op 2-> number
$query .= '`' . $k . '`=';
if($matches[1] == '+') {
$query .= '`' . $k . '`' . $matches[1] . $matches[2] . ',';
}
if($matches[1] == '-') {
$query .= 'GREATEST(cast(`'.$k.'` AS SIGNED) - '.$matches[2].', 0)';
}
}
}
@ -499,7 +495,6 @@ class DB {
}
$query = rtrim($query, $clause.' ');
try {
$db = self::getInstance();
$db->query($query);

View File

@ -16,6 +16,8 @@
namespace G {
use Exception;
/**
* ROUTE HELPERS
* ---------------------------------------------------------------------
@ -736,7 +738,7 @@ namespace G {
$datetime->$action($interval);
}
return $datetime->format('Y-m-d H:i:s');
} catch(\Exception $e) {
} catch(Exception $e) {
throw new Exception($e->getMessage() . ' in ' . __FUNCTION__ . ' (' . $action . ')', $e->getCode());
}
}
@ -745,7 +747,7 @@ namespace G {
try {
$di = new \DateInterval($var);
return $di;
} catch(\Exception $e) {}
} catch(Exception $e) {}
return FALSE;
}
@ -756,15 +758,18 @@ namespace G {
function get_client_ip(){
$client_ip = NULL;
$client_ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : (!empty($_ENV['REMOTE_ADDR']) ? $_ENV['REMOTE_ADDR'] : NULL);
if(array_key_exists('HTTP_CF_CONNECTING_IP', $_SERVER) && $_SERVER['HTTP_CF_CONNECTING_IP'] == $_SERVER['REMOTE_ADDR']) {
return $_SERVER['HTTP_CF_CONNECTING_IP'];
}
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$client_ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ( !empty($_ENV['REMOTE_ADDR']) ? $_ENV['REMOTE_ADDR'] : $client_ip);
$entries = preg_split('/[, ]/', $_SERVER['HTTP_X_FORWARDED_FOR']);
$entries = preg_split('/[\s,]/', $_SERVER['HTTP_X_FORWARDED_FOR'], -1, PREG_SPLIT_NO_EMPTY);
reset($entries);
while(list(, $entry) = each($entries)) {
$entry = trim($entry);
if(preg_match('/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/', $entry, $ip_list)){
@ -783,8 +788,6 @@ namespace G {
}
}
}
} else {
$client_ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : (!empty($_ENV['REMOTE_ADDR']) ? $_ENV['REMOTE_ADDR'] : $client_ip);
}
return $client_ip;
@ -1418,27 +1421,17 @@ namespace G {
*/
function fetch_url($url, $file=NULL) {
if(!$url) {
throw new \Exception('missing $url in G\fetch_url');
throw new Exception('missing $url in ' . __FUNCTION__);
return false;
}
if(ini_get('allow_url_fopen') !== 1 and !function_exists('curl_init')) {
throw new \Exception("allow_url_fopen is disabled and cURL isn't installed");
return false;
if(ini_get('allow_url_fopen') !== 1 && !function_exists('curl_init')) {
throw new Exception("Fatal error in " .__FUNCTION__. ": cURL isn't installed and allow_url_fopen is disabled. Can't perform HTTP requests.");
return FALSE;
}
$version = curl_version();
$ssl_supported = ($version['features'] & CURL_VERSION_SSL);
//$url = preg_replace('/^https/', 'http', $url, 1);
// File get contents is the default fn
$fn = (ini_get('allow_url_fopen') ? 'fgc' : 'curl');
// If fgc isn't available, lets try to use cURL
if($fn == 'curl' and !function_exists('curl_init')) {
throw new \Exception("Neither file_get_contents or cURL can be used to fetch the URL.");
}
// File get contents is the failover fn
$fn = (!function_exists('curl_init') ? 'fgc' : 'curl');
if($fn == 'curl') {
$ch = curl_init();
@ -1446,7 +1439,7 @@ namespace G {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FAILONERROR, 0);
@ -1457,7 +1450,7 @@ namespace G {
// Save the file to $file destination
$out = @fopen($file, 'wb');
if(!$out) {
throw new \Exception("can't open " . __FUNCTION__ . "() file for read and write");
throw new Exception("can't open " . __FUNCTION__ . "() file for read and write");
return false;
}
curl_setopt($ch, CURLOPT_FILE, $out);
@ -1470,7 +1463,7 @@ namespace G {
if(curl_errno($ch)) {
$curl_error = curl_error($ch);
curl_close($ch);
throw new \Exception('curl error: ' . $curl_error);
throw new Exception('curl error: ' . $curl_error);
return false;
}
if($file == NULL) {
@ -1483,12 +1476,12 @@ namespace G {
]);
$result = @file_get_contents($url, FALSE, $context);
if(!$result) {
throw new \Exception("file_get_contents: can't fetch target URL");
throw new Exception("file_get_contents: can't fetch target URL");
return false;
}
if($file) {
if(file_put_contents($file, $result) === false) {
throw new \Exception("file_put_contents: can't fetch target URL");
throw new Exception("file_put_contents: can't fetch target URL");
return false;
}
} else {

View File

@ -5068,6 +5068,8 @@ img.user-image.size-40 , .default-user-image.size-40 {
.copy-hover-display button.copy-input[data-action=copy] {
visibility: hidden;
}
.phone button.copy-input[data-action=copy],
.pablet button.copy-input[data-action=copy],
.copy-hover-display:hover button.copy-input[data-action=copy] {
visibility: visible;
}

View File

@ -1462,7 +1462,7 @@ String.prototype.formatBytes = function(round) {
* Returns the image url.matches (multiple)
*/
String.prototype.match_image_urls = function() {
return this.match(/\b(?:(http[s]?|ftp[s]):\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?(?:jpe?g|gif|png|bmp)\b/gim);
return this.match(/\b(?:(http[s]?|ftp[s]):\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?\.(?:jpe?g|gif|png|bmp)\b/gim);
};
String.prototype.match_urls = function() {

File diff suppressed because one or more lines are too long

View File

@ -89,7 +89,7 @@ return size;};Object.flatten=function(obj,prefix){if(typeof prefix=="undefined")
String.prototype.isEmail=function(){var regex=/^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;return regex.test(this);};String.prototype.getRounded=function(precision,mode){var m,f,isHalf,sgn;precision|=0;m=Math.pow(10,precision);value=this;value*=m;sgn=(value>0)|-(value<0);isHalf=value%1===0.5*sgn;f=Math.floor(value);if(isHalf){switch(mode){case'PHP_ROUND_HALF_DOWN':value=f+(sgn<0);break;case'PHP_ROUND_HALF_EVEN':value=f+(f%2*sgn);break;case'PHP_ROUND_HALF_ODD':value=f+!(f%2);break;default:value=f+(sgn>0);}}
return(isHalf?value:Math.round(value))/ m;};String.prototype.getBytes=function(){var units=["KB","MB","GB","TB","PB","EB","ZB","YB"],suffix=this.toUpperCase().substr(-2);if(units.indexOf(suffix)==-1){return this;}
var pow_factor=units.indexOf(suffix)+1;return parseFloat(this)*Math.pow(1000,pow_factor);};String.prototype.formatBytes=function(round){var bytes=parseInt(this),units=["KB","MB","GB","TB","PB","EB","ZB","YB"];if(!$.isNumeric(this)){return false;}
if(bytes<1000)return bytes+" B";if(typeof round=="undefined")var round=2;for(var i=0;i<units.length;i++){var multiplier=Math.pow(1000,i+1),threshold=multiplier*1000;if(bytes<threshold){var size=bytes / multiplier;return this.getRounded.call(size,round)+" "+units[i];}}};String.prototype.match_image_urls=function(){return this.match(/\b(?:(http[s]?|ftp[s]):\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?(?:jpe?g|gif|png|bmp)\b/gim);};String.prototype.match_urls=function(){return this.match(/\b(?:(http[s]?|ftp[s]):\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?\b/gim);};if(!("indexOf"in Array.prototype)){Array.prototype.indexOf=function(find,i){if(i===undefined)i=0;if(i<0)i+=this.length;if(i<0)i=0;for(var n=this.length;i<n;i++){if(i in this&&this[i]===find){return i;}}
if(bytes<1000)return bytes+" B";if(typeof round=="undefined")var round=2;for(var i=0;i<units.length;i++){var multiplier=Math.pow(1000,i+1),threshold=multiplier*1000;if(bytes<threshold){var size=bytes / multiplier;return this.getRounded.call(size,round)+" "+units[i];}}};String.prototype.match_image_urls=function(){return this.match(/\b(?:(http[s]?|ftp[s]):\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?\.(?:jpe?g|gif|png|bmp)\b/gim);};String.prototype.match_urls=function(){return this.match(/\b(?:(http[s]?|ftp[s]):\/\/)?([^:\/\s]+)(:[0-9]+)?((?:\/\w+)*\/)([\w\-\.]+[^#?\s]+)([^#\s]*)?(#[\w\-]+)?\b/gim);};if(!("indexOf"in Array.prototype)){Array.prototype.indexOf=function(find,i){if(i===undefined)i=0;if(i<0)i+=this.length;if(i<0)i=0;for(var n=this.length;i<n;i++){if(i in this&&this[i]===find){return i;}}
return-1;};}
Array.prototype.array_unique=function(){var result=[];$.each(this,function(i,e){if($.inArray(e,result)==-1)result.push(e);});return result;};PF.fn.deparam=function(querystring){if(typeof querystring=="undefined"||!querystring)return;var obj={},pairs=querystring.replace(/^[\?|&]*/,"").replace(/[&|\?]*$/,"").split("&");for(var i=0;i<pairs.length;i++){var split=pairs[i].split('=');var key=decodeURIComponent(split[0]);var value=decodeURIComponent(split[1]);if(obj.hasOwnProperty(key)&&!value){continue;}
obj[key]=value;}