mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-22 06:15:31 +00:00
Merge branch 'dev' of /home/macgirvin/z into dev
This commit is contained in:
commit
b1b9ee7d60
21 changed files with 1521 additions and 61 deletions
|
@ -698,6 +698,8 @@ function configure_cron_daily {
|
|||
echo "#" >> /var/www/$zotcron
|
||||
echo "shutdown -r now" >> /var/www/$zotcron
|
||||
|
||||
chmod a+x /var/www/$zotcron
|
||||
|
||||
# If global cron job does not exist we add it to /etc/crontab
|
||||
if grep -q $zotcron /etc/crontab
|
||||
then
|
||||
|
|
|
@ -3286,19 +3286,15 @@ class Libzot {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
$f = 'images/' . strtolower(System::get_platform_name()) . '.png';
|
||||
if (file_exists($f)) {
|
||||
$ret['site']['logo'] = z_root() . '/' . $f;
|
||||
}
|
||||
|
||||
|
||||
$ret['site']['about'] = bbcode(get_config('system','siteinfo'), [ 'export' => true ]);
|
||||
$ret['site']['plugins'] = $visible_plugins;
|
||||
$ret['site']['sitehash'] = get_config('system','location_hash');
|
||||
$ret['site']['sitename'] = get_config('system','sitename');
|
||||
$ret['site']['sellpage'] = get_config('system','sellpage');
|
||||
$ret['site']['location'] = get_config('system','site_location');
|
||||
$ret['site']['realm'] = get_directory_realm();
|
||||
$ret['site']['sitename'] = System::get_site_name();
|
||||
$ret['site']['logo'] = System::get_site_icon();
|
||||
$ret['site']['project'] = System::get_platform_name();
|
||||
$ret['site']['version'] = System::get_project_version();
|
||||
}
|
||||
|
|
|
@ -20,11 +20,10 @@ class System {
|
|||
|
||||
static public function get_banner() {
|
||||
|
||||
if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('banner',App::$config['system']))
|
||||
if(is_array(App::$config) && is_array(App::$config['system']) && array_key_exists('banner',App::$config['system']) && App::$config['system']['banner']) {
|
||||
return App::$config['system']['banner'];
|
||||
|
||||
|
||||
return EMPTY_STR;
|
||||
}
|
||||
return self::get_site_name();
|
||||
}
|
||||
|
||||
static public function get_project_icon() {
|
||||
|
@ -32,7 +31,6 @@ class System {
|
|||
return App::$config['system']['icon'];
|
||||
}
|
||||
return z_root() . '/images/' . PLATFORM_NAME . '-64.png';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,13 +53,13 @@ class System {
|
|||
static public function get_notify_icon() {
|
||||
if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['email_notify_icon_url'])
|
||||
return App::$config['system']['email_notify_icon_url'];
|
||||
return z_root() . DEFAULT_NOTIFY_ICON;
|
||||
return self::get_project_icon();
|
||||
}
|
||||
|
||||
static public function get_site_icon() {
|
||||
if(is_array(App::$config) && is_array(App::$config['system']) && App::$config['system']['site_icon_url'])
|
||||
return App::$config['system']['site_icon_url'];
|
||||
return z_root() . DEFAULT_PLATFORM_ICON ;
|
||||
return self::get_project_icon();
|
||||
}
|
||||
|
||||
|
||||
|
|
448
Zotlabs/Module/Admin/Cover_photo.php
Normal file
448
Zotlabs/Module/Admin/Cover_photo.php
Normal file
|
@ -0,0 +1,448 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module\Admin;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\Activity;
|
||||
use Zotlabs\Lib\Libprofile;
|
||||
use Zotlabs\Access\AccessControl;
|
||||
use Zotlabs\Web\Controller;
|
||||
|
||||
/*
|
||||
@file cover_photo.php
|
||||
@brief Module-file with functions for handling of cover-photos
|
||||
|
||||
*/
|
||||
|
||||
require_once('include/attach.php');
|
||||
require_once('include/photo_factory.php');
|
||||
require_once('include/photos.php');
|
||||
|
||||
|
||||
|
||||
/* @brief Initalize the cover-photo edit view
|
||||
*
|
||||
* @param $a Current application
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class Cover_photo {
|
||||
|
||||
function init() {
|
||||
if (! is_site_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
Libprofile::load($channel['channel_address']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Evaluate posted values
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function post() {
|
||||
|
||||
if (! is_site_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
|
||||
check_form_security_token_redirectOnErr('/admin/cover_photo', 'cover_photo');
|
||||
|
||||
if ((array_key_exists('cropfinal',$_POST)) && ($_POST['cropfinal'] == 1)) {
|
||||
|
||||
// phase 2 - we have finished cropping
|
||||
|
||||
if (argc() != 3) {
|
||||
notice( t('Image uploaded but image cropping failed.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$image_id = argv(2);
|
||||
|
||||
if (substr($image_id,-2,1) == '-') {
|
||||
$scale = substr($image_id,-1,1);
|
||||
$image_id = substr($image_id,0,-2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$srcX = intval($_POST['xstart']);
|
||||
$srcY = intval($_POST['ystart']);
|
||||
$srcW = intval($_POST['xfinal']) - $srcX;
|
||||
$srcH = intval($_POST['yfinal']) - $srcY;
|
||||
|
||||
$r = q("select gender from profile where uid = %d and is_default = 1 limit 1",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if ($r) {
|
||||
$profile = array_shift($r);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale > 0 order by imgscale asc LIMIT 1",
|
||||
dbesc($image_id),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if ($r) {
|
||||
|
||||
$max_thumb = intval(get_config('system','max_thumbnail',1600));
|
||||
$iscaled = false;
|
||||
if (intval($r[0]['height']) > $max_thumb || intval($r[0]['width']) > $max_thumb) {
|
||||
$imagick_path = get_config('system','imagick_convert_path');
|
||||
if ($imagick_path && @file_exists($imagick_path) && intval($r[0]['os_storage'])) {
|
||||
|
||||
$fname = dbunescbin($r[0]['content']);
|
||||
$tmp_name = $fname . '-001';
|
||||
$newsize = photo_calculate_scale(array_merge(getimagesize($fname),['max' => $max_thumb]));
|
||||
$cmd = $imagick_path . ' ' . escapeshellarg(PROJECT_BASE . '/' . $fname) . ' -resize ' . $newsize . ' ' . escapeshellarg(PROJECT_BASE . '/' . $tmp_name);
|
||||
// logger('imagick thumbnail command: ' . $cmd);
|
||||
for ($x = 0; $x < 4; $x ++) {
|
||||
exec($cmd);
|
||||
if (file_exists($tmp_name)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (file_exists($tmp_name)) {
|
||||
$base_image = $r[0];
|
||||
$gis = getimagesize($tmp_name);
|
||||
logger('gis: ' . print_r($gis,true));
|
||||
$base_image['width'] = $gis[0];
|
||||
$base_image['height'] = $gis[1];
|
||||
$base_image['content'] = @file_get_contents($tmp_name);
|
||||
$iscaled = true;
|
||||
@unlink($tmp_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (! $iscaled) {
|
||||
$base_image = $r[0];
|
||||
$base_image['content'] = (($base_image['os_storage']) ? @file_get_contents(dbunescbin($base_image['content'])) : dbunescbin($base_image['content']));
|
||||
}
|
||||
|
||||
$im = photo_factory($base_image['content'], $base_image['mimetype']);
|
||||
if ($im->is_valid()) {
|
||||
|
||||
// We are scaling and cropping the relative pixel locations to the original photo instead of the
|
||||
// scaled photo we operated on.
|
||||
|
||||
// First load the scaled photo to check its size. (Should probably pass this in the post form and save
|
||||
// a query.)
|
||||
|
||||
$g = q("select width, height from photo where resource_id = '%s' and uid = %d and imgscale = 3",
|
||||
dbesc($image_id),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
|
||||
$scaled_width = $g[0]['width'];
|
||||
$scaled_height = $g[0]['height'];
|
||||
|
||||
if ((! $scaled_width) || (! $scaled_height)) {
|
||||
logger('potential divide by zero scaling cover photo');
|
||||
return;
|
||||
}
|
||||
|
||||
// unset all other cover photos
|
||||
|
||||
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_COVER),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
$orig_srcx = ( $base_image['width'] / $scaled_width ) * $srcX;
|
||||
$orig_srcy = ( $base_image['height'] / $scaled_height ) * $srcY;
|
||||
$orig_srcw = ( $srcW / $scaled_width ) * $base_image['width'];
|
||||
$orig_srch = ( $srcH / $scaled_height ) * $base_image['height'];
|
||||
|
||||
$im->cropImageRect(1200,435,$orig_srcx, $orig_srcy, $orig_srcw, $orig_srch);
|
||||
|
||||
$aid = get_account_id();
|
||||
|
||||
$p = [
|
||||
'aid' => 0,
|
||||
'uid' => $channel['channel_id'],
|
||||
'resource_id' => $base_image['resource_id'],
|
||||
'filename' => $base_image['filename'],
|
||||
'album' => t('Cover Photos'),
|
||||
'os_path' => $base_image['os_path'],
|
||||
'display_path' => $base_image['display_path'],
|
||||
'created' => $base_image['created'],
|
||||
'edited' => $base_image['edited']
|
||||
];
|
||||
|
||||
$p['imgscale'] = 7;
|
||||
$p['photo_usage'] = PHOTO_COVER;
|
||||
|
||||
$r1 = $im->storeThumbnail($p, PHOTO_RES_COVER_1200);
|
||||
|
||||
$im->doScaleImage(850,310);
|
||||
$p['imgscale'] = 8;
|
||||
|
||||
$r2 = $im->storeThumbnail($p, PHOTO_RES_COVER_850);
|
||||
|
||||
$im->doScaleImage(425,160);
|
||||
$p['imgscale'] = 9;
|
||||
|
||||
$r3 = $im->storeThumbnail($p, PHOTO_RES_COVER_425);
|
||||
|
||||
if ($r1 === false || $r2 === false || $r3 === false) {
|
||||
// if one failed, delete them all so we can start over.
|
||||
notice( t('Image resize failed.') . EOL );
|
||||
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale >= 7 ",
|
||||
dbesc($base_image['resource_id']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
notice( t('Unable to process image') . EOL);
|
||||
}
|
||||
|
||||
goaway(z_root() . '/admin');
|
||||
|
||||
}
|
||||
|
||||
|
||||
$hash = photo_new_resource();
|
||||
$smallest = 0;
|
||||
|
||||
$matches = [];
|
||||
$partial = false;
|
||||
|
||||
if (array_key_exists('HTTP_CONTENT_RANGE',$_SERVER)) {
|
||||
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/',$_SERVER['HTTP_CONTENT_RANGE'],$matches);
|
||||
if ($pm) {
|
||||
logger('Content-Range: ' . print_r($matches,true));
|
||||
$partial = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($partial) {
|
||||
$x = save_chunk($channel,$matches[1],$matches[2],$matches[3]);
|
||||
|
||||
if ($x['partial']) {
|
||||
header('Range: bytes=0-' . (($x['length']) ? $x['length'] - 1 : 0));
|
||||
json_return_and_die($result);
|
||||
}
|
||||
else {
|
||||
header('Range: bytes=0-' . (($x['size']) ? $x['size'] - 1 : 0));
|
||||
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $x['name'],
|
||||
'type' => $x['type'],
|
||||
'tmp_name' => $x['tmp_name'],
|
||||
'error' => $x['error'],
|
||||
'size' => $x['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (! array_key_exists('userfile',$_FILES)) {
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $_FILES['files']['name'],
|
||||
'type' => $_FILES['files']['type'],
|
||||
'tmp_name' => $_FILES['files']['tmp_name'],
|
||||
'error' => $_FILES['files']['error'],
|
||||
'size' => $_FILES['files']['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$res = attach_store($channel, $channel['channel_hash'], '', array('album' => t('Cover Photos'), 'hash' => $hash));
|
||||
|
||||
logger('attach_store: ' . print_r($res,true),LOGGER_DEBUG);
|
||||
|
||||
json_return_and_die([ 'message' => $hash ]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Generate content of profile-photo view
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
if (! is_site_admin()) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
|
||||
$newuser = false;
|
||||
|
||||
if (argc() == 3 && argv(1) === 'new')
|
||||
$newuser = true;
|
||||
|
||||
|
||||
if (argv(2) === 'reset') {
|
||||
q("update photo set photo_usage = %d where photo_usage = %d and uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_COVER),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
}
|
||||
|
||||
if (argv(2) === 'use') {
|
||||
if (argc() < 4) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
};
|
||||
|
||||
// check_form_security_token_redirectOnErr('/cover_photo', 'cover_photo');
|
||||
|
||||
$resource_id = argv(3);
|
||||
|
||||
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' and imgscale > 0 ORDER BY imgscale ASC",
|
||||
intval($channel['channel_id']),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
if (! $r) {
|
||||
notice( t('Photo not available.') . EOL );
|
||||
return;
|
||||
}
|
||||
$havescale = false;
|
||||
foreach ($r as $rr) {
|
||||
if ($rr['imgscale'] == 7) {
|
||||
$havescale = true;
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
|
||||
intval($r[0]['id']),
|
||||
intval($channel['channel_id'])
|
||||
|
||||
);
|
||||
if (! $r) {
|
||||
notice( t('Photo not available.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
if (intval($r[0]['os_storage'])) {
|
||||
$data = @file_get_contents(dbunescbin($r[0]['content']));
|
||||
}
|
||||
else {
|
||||
$data = dbunescbin($r[0]['content']);
|
||||
}
|
||||
|
||||
$ph = photo_factory($data, $r[0]['mimetype']);
|
||||
$smallest = 0;
|
||||
if ($ph->is_valid()) {
|
||||
// go ahead as if we have just uploaded a new photo to crop
|
||||
$i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d and imgscale = 0",
|
||||
dbesc($r[0]['resource_id']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if ($i) {
|
||||
$hash = $i[0]['resource_id'];
|
||||
foreach ($i as $ii) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->cover_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
}
|
||||
|
||||
|
||||
if(! array_key_exists('imagecrop',App::$data)) {
|
||||
|
||||
$o .= replace_macros(get_markup_template('admin_cover_photo.tpl'), [
|
||||
'$user' => $channel['channel_address'],
|
||||
'$channel_id' => $channel['channel_id'],
|
||||
'$info' => t('Your cover photo may be visible to anybody on the internet'),
|
||||
'$existing' => get_cover_photo($channel['channel_id'],'array',PHOTO_RES_COVER_850),
|
||||
'$lbl_upfile' => t('Upload File:'),
|
||||
'$lbl_profiles' => t('Select a profile:'),
|
||||
'$title' => t('Change Cover Photo'),
|
||||
'$submit' => t('Upload'),
|
||||
'$profiles' => $profiles,
|
||||
'$embedPhotos' => t('Use a photo from your albums'),
|
||||
'$embedPhotosModalTitle' => t('Use a photo from your albums'),
|
||||
'$embedPhotosModalCancel' => t('Cancel'),
|
||||
'$embedPhotosModalOK' => t('OK'),
|
||||
'$modalchooseimages' => t('Choose images to embed'),
|
||||
'$modalchoosealbum' => t('Choose an album'),
|
||||
'$modaldiffalbum' => t('Choose a different album'),
|
||||
'$modalerrorlist' => t('Error getting album list'),
|
||||
'$modalerrorlink' => t('Error getting photo link'),
|
||||
'$modalerroralbum' => t('Error getting album'),
|
||||
'$form_security_token' => get_form_security_token("cover_photo"),
|
||||
'$select' => t('Select previously uploaded photo'),
|
||||
|
||||
]);
|
||||
|
||||
call_hooks('cover_photo_content_end', $o);
|
||||
|
||||
return $o;
|
||||
}
|
||||
else {
|
||||
$filename = App::$data['imagecrop'] . '-3';
|
||||
$resolution = 3;
|
||||
|
||||
$o .= replace_macros(get_markup_template('admin_cropcover.tpl'), [
|
||||
'$filename' => $filename,
|
||||
'$profile' => intval($_REQUEST['profile']),
|
||||
'$resource' => \App::$data['imagecrop'] . '-3',
|
||||
'$image_url' => z_root() . '/photo/' . $filename,
|
||||
'$title' => t('Crop Image'),
|
||||
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
|
||||
'$form_security_token' => get_form_security_token("cover_photo"),
|
||||
'$done' => t('Done Editing')
|
||||
]);
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
/* @brief Generate the UI for photo-cropping
|
||||
*
|
||||
* @param $a Current application
|
||||
* @param $ph Photo-Factory
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function cover_photo_crop_ui_head($ph, $hash, $smallest){
|
||||
|
||||
$max_length = get_config('system','max_image_length');
|
||||
if (! $max_length) {
|
||||
$max_length = MAX_IMAGE_LENGTH;
|
||||
}
|
||||
if ($max_length > 0) {
|
||||
$ph->scaleImage($max_length);
|
||||
}
|
||||
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
|
||||
if ($width < 300 || $height < 300) {
|
||||
$ph->scaleImageUp(240);
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
}
|
||||
|
||||
|
||||
App::$data['imagecrop'] = $hash;
|
||||
App::$data['imagecrop_resolution'] = $smallest;
|
||||
App::$page['htmlhead'] .= replace_macros(get_markup_template('crophead.tpl'), []);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
535
Zotlabs/Module/Admin/Profile_photo.php
Normal file
535
Zotlabs/Module/Admin/Profile_photo.php
Normal file
|
@ -0,0 +1,535 @@
|
|||
<?php
|
||||
namespace Zotlabs\Module\Admin;
|
||||
|
||||
/*
|
||||
* @file Profile_photo.php
|
||||
* @brief Module-file with functions for uploading and scaling of profile-photos
|
||||
*
|
||||
*/
|
||||
|
||||
use App;
|
||||
use Zotlabs\Web\Controller;
|
||||
use Zotlabs\Lib\Libsync;
|
||||
use Zotlabs\Lib\Libprofile;
|
||||
use Zotlabs\Lib\Config;
|
||||
use Zotlabs\Daemon\Run;
|
||||
|
||||
|
||||
require_once('include/photo_factory.php');
|
||||
require_once('include/photos.php');
|
||||
|
||||
|
||||
class Profile_photo {
|
||||
|
||||
|
||||
/* @brief Initalize the profile-photo edit view
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function init() {
|
||||
|
||||
if(! is_site_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
Libprofile::load($channel['channel_address']);
|
||||
|
||||
}
|
||||
|
||||
/* @brief Evaluate posted values
|
||||
*
|
||||
* @param $a Current application
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function post() {
|
||||
|
||||
if (! is_site_admin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
|
||||
check_form_security_token_redirectOnErr('/profile_photo', 'profile_photo');
|
||||
|
||||
if ((array_key_exists('cropfinal',$_POST)) && (intval($_POST['cropfinal']) == 1)) {
|
||||
|
||||
// logger('crop: ' . print_r($_POST,true));
|
||||
|
||||
// phase 2 - we have finished cropping
|
||||
|
||||
if (argc() != 3) {
|
||||
notice( t('Image uploaded but image cropping failed.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$image_id = argv(2);
|
||||
|
||||
if (substr($image_id,-2,1) == '-') {
|
||||
$scale = substr($image_id,-1,1);
|
||||
$image_id = substr($image_id,0,-2);
|
||||
}
|
||||
|
||||
// unless proven otherwise
|
||||
$is_default_profile = 1;
|
||||
|
||||
if ($_REQUEST['profile']) {
|
||||
$r = q("select id, profile_guid, is_default, gender from profile where id = %d and uid = %d limit 1",
|
||||
intval($_REQUEST['profile']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if ($r) {
|
||||
$profile = array_shift($r);
|
||||
if (! intval($profile['is_default'])) {
|
||||
$is_default_profile = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$srcX = intval($_POST['xstart']);
|
||||
$srcY = intval($_POST['ystart']);
|
||||
$srcW = intval($_POST['xfinal']) - $srcX;
|
||||
$srcH = intval($_POST['yfinal']) - $srcY;
|
||||
|
||||
$r = q("SELECT * FROM photo WHERE resource_id = '%s' AND uid = %d AND imgscale = %d LIMIT 1",
|
||||
dbesc($image_id),
|
||||
dbesc($channel['channel_id']),
|
||||
intval($scale));
|
||||
if ($r) {
|
||||
|
||||
$base_image = array_shift($r);
|
||||
$base_image['content'] = (($base_image['os_storage']) ? @file_get_contents(dbunescbin($base_image['content'])) : dbunescbin($base_image['content']));
|
||||
|
||||
$im = photo_factory($base_image['content'], $base_image['mimetype']);
|
||||
if ($im->is_valid()) {
|
||||
|
||||
$im->cropImage(300,$srcX,$srcY,$srcW,$srcH);
|
||||
|
||||
$aid = 0;
|
||||
|
||||
$p = [
|
||||
'aid' => $aid,
|
||||
'uid' => $channel['channel_id'],
|
||||
'resource_id' => $base_image['resource_id'],
|
||||
'filename' => $base_image['filename'],
|
||||
'album' => t('Profile Photos'),
|
||||
'os_path' => $base_image['os_path'],
|
||||
'display_path' => $base_image['display_path'],
|
||||
'created' => $base_image['created'],
|
||||
'edited' => $base_image['edited']
|
||||
];
|
||||
|
||||
$p['imgscale'] = PHOTO_RES_PROFILE_300;
|
||||
$p['photo_usage'] = (($is_default_profile) ? PHOTO_PROFILE : PHOTO_NORMAL);
|
||||
|
||||
$r1 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_300);
|
||||
|
||||
$im->scaleImage(80);
|
||||
$p['imgscale'] = PHOTO_RES_PROFILE_80;
|
||||
|
||||
$r2 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_80);
|
||||
|
||||
$im->scaleImage(48);
|
||||
$p['imgscale'] = PHOTO_RES_PROFILE_48;
|
||||
|
||||
$r3 = $im->storeThumbnail($p, PHOTO_RES_PROFILE_48);
|
||||
|
||||
if ($r1 === false || $r2 === false || $r3 === false) {
|
||||
// if one failed, delete them all so we can start over.
|
||||
notice( t('Image resize failed.') . EOL );
|
||||
$x = q("delete from photo where resource_id = '%s' and uid = %d and imgscale in ( %d, %d, %d ) ",
|
||||
dbesc($base_image['resource_id']),
|
||||
$channel['channel_id'],
|
||||
intval(PHOTO_RES_PROFILE_300),
|
||||
intval(PHOTO_RES_PROFILE_80),
|
||||
intval(PHOTO_RES_PROFILE_48)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d
|
||||
AND resource_id != '%s' AND uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_PROFILE),
|
||||
dbesc($base_image['resource_id']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
// We'll set the updated profile-photo timestamp even if it isn't the default profile,
|
||||
// so that browsers will do a cache update unconditionally
|
||||
// Also set links back to site-specific profile photo url in case it was
|
||||
// changed to a generic URL by a clone operation. Otherwise the new photo may
|
||||
// not get pushed to other sites correctly.
|
||||
|
||||
$r = q("UPDATE xchan set xchan_photo_mimetype = '%s', xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s'
|
||||
where xchan_hash = '%s'",
|
||||
dbesc($im->getType()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(z_root() . '/photo/profile/l/' . $channel['channel_id']),
|
||||
dbesc(z_root() . '/photo/profile/m/' . $channel['channel_id']),
|
||||
dbesc(z_root() . '/photo/profile/s/' . $channel['channel_id']),
|
||||
dbesc($channel['xchan_hash'])
|
||||
);
|
||||
|
||||
// Similarly, tell the nav bar to bypass the cache and update the avatar image.
|
||||
$_SESSION['reload_avatar'] = true;
|
||||
Config::Set('system','site_icon_url',z_root() . '/photo/profile/m/' . $channel['channel_id']);
|
||||
|
||||
info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL);
|
||||
|
||||
}
|
||||
else {
|
||||
notice( t('Unable to process image') . EOL);
|
||||
}
|
||||
}
|
||||
|
||||
goaway(z_root() . '/admin');
|
||||
}
|
||||
|
||||
// A new photo was uploaded. Store it and save some important details
|
||||
// in App::$data for use in the cropping function
|
||||
|
||||
|
||||
$hash = photo_new_resource();
|
||||
$importing = false;
|
||||
$smallest = 0;
|
||||
|
||||
|
||||
if ($_REQUEST['importfile']) {
|
||||
$hash = $_REQUEST['importfile'];
|
||||
$importing = true;
|
||||
}
|
||||
else {
|
||||
|
||||
$matches = [];
|
||||
$partial = false;
|
||||
|
||||
if (array_key_exists('HTTP_CONTENT_RANGE',$_SERVER)) {
|
||||
$pm = preg_match('/bytes (\d*)\-(\d*)\/(\d*)/',$_SERVER['HTTP_CONTENT_RANGE'],$matches);
|
||||
if ($pm) {
|
||||
logger('Content-Range: ' . print_r($matches,true), LOGGER_DEBUG);
|
||||
$partial = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($partial) {
|
||||
$x = save_chunk($channel,$matches[1],$matches[2],$matches[3]);
|
||||
|
||||
if ($x['partial']) {
|
||||
header('Range: bytes=0-' . (($x['length']) ? $x['length'] - 1 : 0));
|
||||
json_return_and_die($result);
|
||||
}
|
||||
else {
|
||||
header('Range: bytes=0-' . (($x['size']) ? $x['size'] - 1 : 0));
|
||||
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $x['name'],
|
||||
'type' => $x['type'],
|
||||
'tmp_name' => $x['tmp_name'],
|
||||
'error' => $x['error'],
|
||||
'size' => $x['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (! array_key_exists('userfile',$_FILES)) {
|
||||
$_FILES['userfile'] = [
|
||||
'name' => $_FILES['files']['name'],
|
||||
'type' => $_FILES['files']['type'],
|
||||
'tmp_name' => $_FILES['files']['tmp_name'],
|
||||
'error' => $_FILES['files']['error'],
|
||||
'size' => $_FILES['files']['size']
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$res = attach_store($channel, $channel['channel_hash'], '', array('album' => t('Profile Photos'), 'hash' => $hash));
|
||||
|
||||
logger('attach_store: ' . print_r($res,true), LOGGER_DEBUG);
|
||||
|
||||
json_return_and_die([ 'message' => $hash ]);
|
||||
}
|
||||
|
||||
if (($res && intval($res['data']['is_photo'])) || $importing) {
|
||||
$i = q("select * from photo where resource_id = '%s' and uid = %d order by imgscale",
|
||||
dbesc($hash),
|
||||
intval($channel['channel_hash'])
|
||||
);
|
||||
|
||||
if (! $i) {
|
||||
notice( t('Image upload failed.') . EOL );
|
||||
return;
|
||||
}
|
||||
$os_storage = false;
|
||||
|
||||
foreach ($i as $ii) {
|
||||
if (intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
$os_storage = intval($ii['os_storage']);
|
||||
$imagedata = $ii['content'];
|
||||
$filetype = $ii['mimetype'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$imagedata = (($os_storage) ? @file_get_contents(dbunescbin($imagedata)) : dbunescbin($imagedata));
|
||||
$ph = photo_factory($imagedata, $filetype);
|
||||
|
||||
if (! $ph->is_valid()) {
|
||||
notice( t('Unable to process image.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->profile_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
|
||||
// This will "fall through" to the get() method, and since
|
||||
// App::$data['imagecrop'] is set, it will proceed to cropping
|
||||
// rather than present the upload form
|
||||
}
|
||||
|
||||
|
||||
/* @brief Generate content of profile-photo view
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function get() {
|
||||
|
||||
if (! is_site_admin()) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
$channel = get_sys_channel();
|
||||
$pf = 0;
|
||||
$newuser = false;
|
||||
|
||||
if (argc() == 3 && argv(2) === 'new') {
|
||||
$newuser = true;
|
||||
}
|
||||
|
||||
if (argv(2) === 'reset') {
|
||||
Config::Delete('system','site_icon_url');
|
||||
}
|
||||
|
||||
if (argv(2) === 'use') {
|
||||
if (argc() < 4) {
|
||||
notice( t('Permission denied.') . EOL );
|
||||
return;
|
||||
};
|
||||
|
||||
$resource_id = argv(3);
|
||||
|
||||
$pf = (($_REQUEST['pf']) ? intval($_REQUEST['pf']) : 0);
|
||||
|
||||
$c = q("select id, is_default from profile where uid = %d",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
$multi_profiles = true;
|
||||
|
||||
if (($c) && (count($c) === 1) && (intval($c[0]['is_default']))) {
|
||||
$_REQUEST['profile'] = $c[0]['id'];
|
||||
$multi_profiles = false;
|
||||
}
|
||||
else {
|
||||
$_REQUEST['profile'] = $pf;
|
||||
}
|
||||
|
||||
$r = q("SELECT id, album, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' ORDER BY imgscale ASC",
|
||||
intval($channel['channel_id']),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
if (! $r) {
|
||||
notice( t('Photo not available.') . EOL );
|
||||
return;
|
||||
}
|
||||
$havescale = false;
|
||||
foreach ($r as $rr) {
|
||||
if ($rr['imgscale'] == PHOTO_RES_PROFILE_80) {
|
||||
$havescale = true;
|
||||
}
|
||||
}
|
||||
|
||||
// set an already loaded and cropped photo as profile photo
|
||||
|
||||
if ($havescale) {
|
||||
// unset any existing profile photos
|
||||
$r = q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND uid = %d",
|
||||
intval(PHOTO_NORMAL),
|
||||
intval(PHOTO_PROFILE),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
$r = q("UPDATE photo SET photo_usage = %d WHERE uid = %d AND resource_id = '%s'",
|
||||
intval(PHOTO_PROFILE),
|
||||
intval($channel['channel_id']),
|
||||
dbesc($resource_id)
|
||||
);
|
||||
|
||||
$r = q("UPDATE xchan set xchan_photo_date = '%s' where xchan_hash = '%s'",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($channel['xchan_hash'])
|
||||
);
|
||||
|
||||
goaway(z_root() . '/admin');
|
||||
}
|
||||
|
||||
$r = q("SELECT content, mimetype, resource_id, os_storage FROM photo WHERE id = %d and uid = %d limit 1",
|
||||
intval($r[0]['id']),
|
||||
intval($channel['channel_id'])
|
||||
|
||||
);
|
||||
if (! $r) {
|
||||
notice( t('Photo not available.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
if (intval($r[0]['os_storage'])) {
|
||||
$data = @file_get_contents(dbunescbin($r[0]['content']));
|
||||
}
|
||||
else {
|
||||
$data = dbunescbin($r[0]['content']);
|
||||
}
|
||||
|
||||
$ph = photo_factory($data, $r[0]['mimetype']);
|
||||
$smallest = 0;
|
||||
if ($ph->is_valid()) {
|
||||
// go ahead as if we have just uploaded a new photo to crop
|
||||
$i = q("select resource_id, imgscale from photo where resource_id = '%s' and uid = %d order by imgscale",
|
||||
dbesc($r[0]['resource_id']),
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if ($i) {
|
||||
$hash = $i[0]['resource_id'];
|
||||
foreach ($i as $ii) {
|
||||
if (intval($ii['imgscale']) < PHOTO_RES_640) {
|
||||
$smallest = intval($ii['imgscale']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($multi_profiles) {
|
||||
App::$data['importfile'] = $resource_id;
|
||||
}
|
||||
else {
|
||||
$this->profile_photo_crop_ui_head($ph, $hash, $smallest);
|
||||
}
|
||||
|
||||
// falls through with App::$data['imagecrop'] set so we go straight to the cropping section
|
||||
|
||||
}
|
||||
|
||||
// present an upload form
|
||||
|
||||
$profiles = q("select id, profile_name as name, is_default from profile where uid = %d order by id asc",
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
|
||||
if ($profiles) {
|
||||
for ($x = 0; $x < count($profiles); $x ++) {
|
||||
$profiles[$x]['selected'] = false;
|
||||
if ($pf && $profiles[$x]['id'] == $pf) {
|
||||
$profiles[$x]['selected'] = true;
|
||||
}
|
||||
if ((! $pf) && $profiles[$x]['is_default']) {
|
||||
$profiles[$x]['selected'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$importing = ((array_key_exists('importfile',App::$data)) ? true : false);
|
||||
|
||||
if (! array_key_exists('imagecrop', App::$data)) {
|
||||
|
||||
$tpl = get_markup_template('admin_profile_photo.tpl');
|
||||
|
||||
$o .= replace_macros($tpl, [
|
||||
'$user' => $channel['channel_address'],
|
||||
'$channel_id' => $channel['channel_id'],
|
||||
'$info' => ((count($profiles) > 1) ? t('Your default profile photo is visible to anybody on the internet. Profile photos for alternate profiles will inherit the permissions of the profile') : t('Your site photo is visible to anybody on the internet and may be distributed to other websites.')),
|
||||
'$importfile' => (($importing) ? App::$data['importfile'] : ''),
|
||||
'$lbl_upfile' => t('Upload File:'),
|
||||
'$lbl_profiles' => t('Select a profile:'),
|
||||
'$title' => (($importing) ? t('Use Photo for Site Logo') : t('Change Site Logo')),
|
||||
'$submit' => (($importing) ? t('Use') : t('Upload')),
|
||||
'$profiles' => $profiles,
|
||||
'$single' => ((count($profiles) == 1) ? true : false),
|
||||
'$profile0' => $profiles[0],
|
||||
'$embedPhotos' => t('Use a photo from your albums'),
|
||||
'$embedPhotosModalTitle' => t('Use a photo from your albums'),
|
||||
'$embedPhotosModalCancel' => t('Cancel'),
|
||||
'$embedPhotosModalOK' => t('OK'),
|
||||
'$modalchooseimages' => t('Choose images to embed'),
|
||||
'$modalchoosealbum' => t('Choose an album'),
|
||||
'$modaldiffalbum' => t('Choose a different album'),
|
||||
'$modalerrorlist' => t('Error getting album list'),
|
||||
'$modalerrorlink' => t('Error getting photo link'),
|
||||
'$modalerroralbum' => t('Error getting album'),
|
||||
'$form_security_token' => get_form_security_token("profile_photo"),
|
||||
'$select' => t('Select previously uploaded photo'),
|
||||
]);
|
||||
|
||||
call_hooks('profile_photo_content_end', $o);
|
||||
return $o;
|
||||
}
|
||||
else {
|
||||
|
||||
// present a cropping form
|
||||
|
||||
$filename = App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution'];
|
||||
$resolution = App::$data['imagecrop_resolution'];
|
||||
$o .= replace_macros(get_markup_template('admin_cropbody.tpl'), [
|
||||
'$filename' => $filename,
|
||||
'$profile' => intval($_REQUEST['profile']),
|
||||
'$resource' => App::$data['imagecrop'] . '-' . App::$data['imagecrop_resolution'],
|
||||
'$image_url' => z_root() . '/photo/' . $filename,
|
||||
'$title' => t('Crop Image'),
|
||||
'$desc' => t('Please adjust the image cropping for optimum viewing.'),
|
||||
'$form_security_token' => get_form_security_token("profile_photo"),
|
||||
'$done' => t('Done Editing')
|
||||
]);
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
|
||||
/* @brief Generate the UI for photo-cropping
|
||||
*
|
||||
* @param $ph Photo-Factory
|
||||
* @return void
|
||||
*
|
||||
*/
|
||||
|
||||
function profile_photo_crop_ui_head($ph, $hash, $smallest) {
|
||||
$max_length = get_config('system','max_image_length');
|
||||
if (! $max_length) {
|
||||
$max_length = MAX_IMAGE_LENGTH;
|
||||
}
|
||||
if ($max_length > 0) {
|
||||
$ph->scaleImage($max_length);
|
||||
}
|
||||
|
||||
App::$data['width'] = $ph->getWidth();
|
||||
App::$data['height'] = $ph->getHeight();
|
||||
|
||||
if (App::$data['width'] < 500 || App::$data['height'] < 500) {
|
||||
$ph->scaleImageUp(400);
|
||||
App::$data['width'] = $ph->getWidth();
|
||||
App::$data['height'] = $ph->getHeight();
|
||||
}
|
||||
|
||||
App::$data['imagecrop'] = $hash;
|
||||
App::$data['imagecrop_resolution'] = $smallest;
|
||||
App::$page['htmlhead'] .= replace_macros(get_markup_template('crophead.tpl'), []);
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -25,8 +25,6 @@ class Site {
|
|||
|
||||
$sitename = ((x($_POST,'sitename')) ? notags(trim($_POST['sitename'])) : '');
|
||||
|
||||
$banner = ((x($_POST,'banner')) ? trim($_POST['banner']) : false);
|
||||
|
||||
$admininfo = ((x($_POST,'admininfo')) ? trim($_POST['admininfo']) : false);
|
||||
$siteinfo = ((x($_POST,'siteinfo')) ? trim($_POST['siteinfo']) : '');
|
||||
$language = ((x($_POST,'language')) ? notags(trim($_POST['language'])) : 'en');
|
||||
|
@ -123,13 +121,6 @@ class Site {
|
|||
set_config('system','directory_server',$directory_server);
|
||||
}
|
||||
|
||||
if ($banner == '') {
|
||||
del_config('system', 'banner');
|
||||
}
|
||||
else {
|
||||
set_config('system', 'banner', $banner);
|
||||
}
|
||||
|
||||
if ($admininfo == '') {
|
||||
del_config('system', 'admininfo');
|
||||
}
|
||||
|
@ -250,11 +241,6 @@ class Site {
|
|||
}
|
||||
}
|
||||
|
||||
/* Banner */
|
||||
|
||||
$banner = System::get_banner();
|
||||
|
||||
$banner = htmlspecialchars($banner);
|
||||
|
||||
/* Admin Info */
|
||||
|
||||
|
@ -304,7 +290,6 @@ class Site {
|
|||
'$advanced' => t('Advanced'),
|
||||
'$baseurl' => z_root(),
|
||||
'$sitename' => [ 'sitename', t("Site name"), htmlspecialchars(get_config('system','sitename'), ENT_QUOTES, 'UTF-8'),'' ],
|
||||
'$banner' => [ 'banner', t("Banner/Logo"), $banner, t('Unfiltered HTML/CSS/JS is allowed') ],
|
||||
'$admininfo' => [ 'admininfo', t("Administrator Information"), $admininfo, t("Contact information for site administrators. Displayed on siteinfo page. BBCode may be used here.") ],
|
||||
'$siteinfo' => [ 'siteinfo', t('Site Information'), get_config('system','siteinfo'), t("Publicly visible description of this site. Displayed on siteinfo page. BBCode may be used here.") ],
|
||||
'$language' => [ 'language', t("System language"), get_config('system','language','en'), "", $lang_choices ],
|
||||
|
|
|
@ -16,18 +16,29 @@ class Embedphotos extends Controller {
|
|||
*
|
||||
*/
|
||||
function post() {
|
||||
|
||||
// The admin tools for setting a site logo and cover photo set the channel_id explicitly
|
||||
// to the 'sys' channel and use stored resources for that channel.
|
||||
// Legacy behaviour uses the local logged in channel.
|
||||
|
||||
if (argc() > 2 && is_site_admin() && intval(argv(2))) {
|
||||
$channel_id = argv(2);
|
||||
}
|
||||
else {
|
||||
$channel_id = local_channel();
|
||||
}
|
||||
if (argc() > 1 && argv(1) === 'album') {
|
||||
// API: /embedphotos/album
|
||||
$name = (x($_POST,'name') ? $_POST['name'] : null );
|
||||
if (! $name) {
|
||||
json_return_and_die(array('errormsg' => 'Error retrieving album', 'status' => false));
|
||||
}
|
||||
$album = $this->embedphotos_widget_album(array('channel_id' => local_channel(), 'album' => $name));
|
||||
$album = $this->embedphotos_widget_album(array('channel_id' => $channel_id, 'album' => $name));
|
||||
json_return_and_die(array('status' => true, 'content' => $album));
|
||||
}
|
||||
if (argc() > 1 && argv(1) === 'albumlist') {
|
||||
// API: /embedphotos/albumlist
|
||||
$album_list = $this->embedphotos_album_list();
|
||||
$album_list = $this->embedphotos_album_list($channel_id);
|
||||
json_return_and_die(array('status' => true, 'albumlist' => $album_list));
|
||||
}
|
||||
if (argc() > 1 && argv(1) === 'photolink') {
|
||||
|
@ -38,7 +49,7 @@ class Embedphotos extends Controller {
|
|||
}
|
||||
$resource_id = array_pop(explode("/", $href));
|
||||
|
||||
$x = self::photolink($resource_id);
|
||||
$x = self::photolink($resource_id, $channel_id);
|
||||
if ($x) {
|
||||
json_return_and_die(array('status' => true, 'photolink' => $x, 'resource_id' => $resource_id));
|
||||
}
|
||||
|
@ -48,8 +59,14 @@ class Embedphotos extends Controller {
|
|||
}
|
||||
|
||||
|
||||
protected static function photolink($resource) {
|
||||
$channel = App::get_channel();
|
||||
protected static function photolink($resource, $channel_id = 0) {
|
||||
if (intval($channel_id)) {
|
||||
$channel = channelx_by_n($channel_id);
|
||||
}
|
||||
else {
|
||||
$channel = App::get_channel();
|
||||
}
|
||||
|
||||
$output = EMPTY_STR;
|
||||
if ($channel) {
|
||||
$resolution = ((feature_enabled($channel['channel_id'],'large_photos')) ? 1 : 2);
|
||||
|
@ -216,8 +233,9 @@ class Embedphotos extends Controller {
|
|||
return $o;
|
||||
}
|
||||
|
||||
function embedphotos_album_list() {
|
||||
$p = photos_albums_list(App::get_channel(),App::get_observer());
|
||||
function embedphotos_album_list($channel_id) {
|
||||
$channel = channelx_by_n($channel_id);
|
||||
$p = photos_albums_list($channel,App::get_observer());
|
||||
if ($p['success']) {
|
||||
return $p['albums'];
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ class Sites extends \Zotlabs\Web\Controller {
|
|||
|
||||
|
||||
$sitename = get_sconfig($rr['site_url'],'system','sitename',$rr['site_url']);
|
||||
if ($sitename !== $rr['site_url']) {
|
||||
$sitename .= ' (' . $rr['site_url'] . ')';
|
||||
}
|
||||
$disabled = (($access === 'private' || $register === 'closed') ? true : false);
|
||||
$logo = get_sconfig($rr['site_url'],'system','logo');
|
||||
$about = get_sconfig($rr['site_url'],'system','about');
|
||||
|
|
|
@ -19,16 +19,18 @@ class Admin {
|
|||
// array( url, name, extra css classes )
|
||||
|
||||
$aside = [
|
||||
'site' => array(z_root() . '/admin/site/', t('Site'), 'site'),
|
||||
'accounts' => array(z_root() . '/admin/accounts/', t('Accounts'), 'accounts', 'pending-update', t('Member registrations waiting for confirmation')),
|
||||
'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'),
|
||||
'security' => array(z_root() . '/admin/security/', t('Security'), 'security'),
|
||||
// 'features' => array(z_root() . '/admin/features/', t('Features'), 'features'),
|
||||
'addons' => array(z_root() . '/admin/addons/', t('Addons'), 'addons'),
|
||||
'themes' => array(z_root() . '/admin/themes/', t('Themes'), 'themes'),
|
||||
'queue' => array(z_root() . '/admin/queue', t('Inspect queue'), 'queue'),
|
||||
// 'profs' => array(z_root() . '/admin/profs', t('Profile Fields'), 'profs'),
|
||||
'dbsync' => array(z_root() . '/admin/dbsync/', t('DB updates'), 'dbsync')
|
||||
'site' => array(z_root() . '/admin/site/', t('Site'), 'site'),
|
||||
'profile_photo' => array(z_root() . '/admin/profile_photo', t('Site icon/logo'), 'profile_photo'),
|
||||
'cover_photo' => array(z_root() . '/admin/cover_photo', t('Site photo'), 'cover_photo'),
|
||||
'accounts' => array(z_root() . '/admin/accounts/', t('Accounts'), 'accounts', 'pending-update', t('Member registrations waiting for confirmation')),
|
||||
'channels' => array(z_root() . '/admin/channels/', t('Channels'), 'channels'),
|
||||
'security' => array(z_root() . '/admin/security/', t('Security'), 'security'),
|
||||
// 'features' => array(z_root() . '/admin/features/', t('Features'), 'features'),
|
||||
'addons' => array(z_root() . '/admin/addons/', t('Addons'), 'addons'),
|
||||
'themes' => array(z_root() . '/admin/themes/', t('Themes'), 'themes'),
|
||||
'queue' => array(z_root() . '/admin/queue', t('Inspect queue'), 'queue'),
|
||||
// 'profs' => array(z_root() . '/admin/profs', t('Profile Fields'), 'profs'),
|
||||
'dbsync' => array(z_root() . '/admin/dbsync/', t('DB updates'), 'dbsync')
|
||||
];
|
||||
|
||||
/* get plugins admin page */
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace Zotlabs\Widget;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Lib\System;
|
||||
|
||||
class Cover_photo {
|
||||
|
||||
function widget($arr) {
|
||||
|
@ -9,10 +12,20 @@ class Cover_photo {
|
|||
require_once('include/channel.php');
|
||||
$o = '';
|
||||
|
||||
|
||||
if(\App::$module == 'channel' && $_REQUEST['mid'])
|
||||
return '';
|
||||
|
||||
$channel_id = 0;
|
||||
|
||||
$site_banner = false;
|
||||
|
||||
if (App::$module === 'home') {
|
||||
$channel = get_sys_channel();
|
||||
$channel_id = $channel['channel_id'];
|
||||
$site_banner = System::get_site_name();
|
||||
}
|
||||
|
||||
if(array_key_exists('channel_id', $arr) && intval($arr['channel_id']))
|
||||
$channel_id = intval($arr['channel_id']);
|
||||
if(! $channel_id)
|
||||
|
@ -47,11 +60,18 @@ class Cover_photo {
|
|||
else
|
||||
$title = $channel['channel_name'];
|
||||
|
||||
|
||||
if(array_key_exists('subtitle', $arr) && isset($arr['subtitle']))
|
||||
$subtitle = $arr['subtitle'];
|
||||
else
|
||||
$subtitle = str_replace('@','@',$channel['xchan_addr']);
|
||||
|
||||
|
||||
if ($site_banner) {
|
||||
$title = $site_banner;
|
||||
$subtitle = '';
|
||||
}
|
||||
|
||||
$c = get_cover_photo($channel_id,'html');
|
||||
|
||||
if($c) {
|
||||
|
|
3
boot.php
3
boot.php
|
@ -16,7 +16,7 @@ use Zotlabs\Daemon\Run;
|
|||
* @brief This file defines some global constants and includes the central App class.
|
||||
*/
|
||||
|
||||
define ( 'STD_VERSION', '20.09.09' );
|
||||
define ( 'STD_VERSION', '20.09.10' );
|
||||
define ( 'ZOT_REVISION', '6.0' );
|
||||
|
||||
define ( 'DB_UPDATE_VERSION', 1242 );
|
||||
|
@ -2233,7 +2233,6 @@ function construct_page() {
|
|||
call_hooks('construct_page', $arr);
|
||||
App::$layout = $arr['layout'];
|
||||
|
||||
|
||||
foreach(App::$layout as $k => $v) {
|
||||
if((strpos($k, 'region_') === 0) && strlen($v)) {
|
||||
if(strpos($v, '$region_') !== false) {
|
||||
|
|
|
@ -86,7 +86,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
|
|||
if($r) {
|
||||
foreach($r as $rr) {
|
||||
$selected = (($single_group && $rr['hash'] === $allow_gid[0]) ? ' selected = "selected" ' : '');
|
||||
$groups .= '<option id="' . $rr['id'] . '" value="' . $rr['hash'] . '"' . $selected . '>' . $rr['gname'] . '</option>' . "\r\n";
|
||||
$groups .= '<option id="' . $rr['id'] . '" value="' . $rr['hash'] . '"' . $selected . '>' . $rr['gname'] . ' ' . t('(List)') . '</option>' . "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
|
|||
if($forums) {
|
||||
foreach($forums as $f) {
|
||||
$selected = (($single_group && $f['hash'] === $allow_cid[0]) ? ' selected = "selected" ' : '');
|
||||
$groups .= '<option id="^' . $f['abook_id'] . '" value="^' . $f['xchan_hash'] . '"' . $selected . '>' . $f['xchan_name'] . '</option>' . "\r\n";
|
||||
$groups .= '<option id="^' . $f['abook_id'] . '" value="^' . $f['xchan_hash'] . '"' . $selected . '>' . $f['xchan_name'] . ' ' . t('(Group)') . '</option>' . "\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,9 +47,9 @@ function nav($template = 'default') {
|
|||
|
||||
$channel_apps[] = channel_apps($is_owner, App::$profile['channel_address']);
|
||||
|
||||
$project_icon = System::get_project_icon();
|
||||
$site_icon = System::get_site_icon();
|
||||
|
||||
$banner = System::get_banner();
|
||||
$banner = System::get_site_name();
|
||||
|
||||
App::$page['header'] .= replace_macros(get_markup_template('hdr.tpl'), array(
|
||||
//we could additionally use this to display important system notifications e.g. for updates
|
||||
|
@ -284,7 +284,7 @@ function nav($template = 'default') {
|
|||
|
||||
App::$page['nav'] .= replace_macros($tpl, array(
|
||||
'$baseurl' => z_root(),
|
||||
'$project_icon' => $project_icon,
|
||||
'$project_icon' => $site_icon,
|
||||
'$project_title' => t('Powered by $Projectname'),
|
||||
'$fulldocs' => t('Help'),
|
||||
'$sitelocation' => $sitelocation,
|
||||
|
|
3
view/pdl/mod_home.pdl
Normal file
3
view/pdl/mod_home.pdl
Normal file
|
@ -0,0 +1,3 @@
|
|||
[region=banner]
|
||||
[widget=cover_photo][/widget]
|
||||
[/region]
|
|
@ -15,11 +15,6 @@ html {
|
|||
margin-right: 1.5rem;
|
||||
}
|
||||
|
||||
.project-banner img {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.project-banner a {
|
||||
color: $banner_colour;
|
||||
}
|
||||
|
@ -1301,7 +1296,7 @@ img.mail-conv-sender-photo {
|
|||
width: 3.75rem;
|
||||
}
|
||||
|
||||
#avatar {
|
||||
#avatar, .nav-avatar {
|
||||
width: 2.35rem;
|
||||
height: 2.35rem;
|
||||
border-radius: $radius;
|
||||
|
|
167
view/tpl/admin_cover_photo.tpl
Executable file
167
view/tpl/admin_cover_photo.tpl
Executable file
|
@ -0,0 +1,167 @@
|
|||
<script src="vendor/blueimp/jquery-file-upload/js/vendor/jquery.ui.widget.js"></script>
|
||||
<script src="vendor/blueimp/jquery-file-upload/js/jquery.iframe-transport.js"></script>
|
||||
<script src="vendor/blueimp/jquery-file-upload/js/jquery.fileupload.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
var initializeEmbedPhotoDialog = function () {
|
||||
$('.embed-photo-selected-photo').each(function (index) {
|
||||
$(this).removeClass('embed-photo-selected-photo');
|
||||
});
|
||||
getPhotoAlbumList();
|
||||
$('#embedPhotoModalBodyAlbumDialog').off('click');
|
||||
$('#embedPhotoModal').modal('show');
|
||||
};
|
||||
|
||||
var choosePhotoFromAlbum = function (album) {
|
||||
$.post("embedphotos/album/{{$channel_id}}", {name: album},
|
||||
function(data) {
|
||||
if (data['status']) {
|
||||
$('#embedPhotoModalLabel').html("{{$modalchooseimages}}");
|
||||
$('#embedPhotoModalBodyAlbumDialog').html('\
|
||||
<div><div class="nav nav-pills flex-column">\n\
|
||||
<li class="nav-item"><a class="nav-link" href="#" onclick="initializeEmbedPhotoDialog();return false;">\n\
|
||||
<i class="fa fa-chevron-left"></i> \n\
|
||||
{{$modaldiffalbum}}\n\
|
||||
</a>\n\
|
||||
</li>\n\
|
||||
</div><br></div>')
|
||||
$('#embedPhotoModalBodyAlbumDialog').append(data['content']);
|
||||
$('#embedPhotoModalBodyAlbumDialog').click(function (evt) {
|
||||
evt.preventDefault();
|
||||
var image = document.getElementById(evt.target.id);
|
||||
if (typeof($(image).parent()[0]) !== 'undefined') {
|
||||
var imageparent = document.getElementById($(image).parent()[0].id);
|
||||
$(imageparent).toggleClass('embed-photo-selected-photo');
|
||||
var href = $(imageparent).attr('href');
|
||||
$.post("embedphotos/photolink/{{$channel_id}}", {href: href},
|
||||
function(ddata) {
|
||||
if (ddata['status']) {
|
||||
window.location.href = 'admin/cover_photo/use/' + ddata['resource_id'];
|
||||
} else {
|
||||
window.console.log("{{$modalerrorlink}}" + ':' + ddata['errormsg']);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
'json');
|
||||
$('#embedPhotoModalBodyAlbumDialog').html('');
|
||||
$('#embedPhotoModalBodyAlbumDialog').off('click');
|
||||
$('#embedPhotoModal').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
$('#embedPhotoModalBodyAlbumListDialog').addClass('d-none');
|
||||
$('#embedPhotoModalBodyAlbumDialog').removeClass('d-none');
|
||||
} else {
|
||||
window.console.log("{{$modalerroralbum}} " + JSON.stringify(album) + ':' + data['errormsg']);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
'json');
|
||||
};
|
||||
|
||||
var getPhotoAlbumList = function () {
|
||||
$.post("embedphotos/albumlist/{{$channel_id}}", {},
|
||||
function(data) {
|
||||
if (data['status']) {
|
||||
var albums = data['albumlist']; //JSON.parse(data['albumlist']);
|
||||
$('#embedPhotoModalLabel').html("{{$modalchoosealbum}}");
|
||||
$('#embedPhotoModalBodyAlbumList').html('<ul class="nav nav-pills flex-column"></ul>');
|
||||
for(var i=0; i<albums.length; i++) {
|
||||
var albumName = albums[i].text;
|
||||
var jsAlbumName = albums[i].jstext;
|
||||
var albumLink = '<li class="nav-item">';
|
||||
albumLink += '<a class="nav-link" href="#" onclick="choosePhotoFromAlbum(\'' + jsAlbumName + '\'); return false;">' + albumName + '</a>';
|
||||
albumLink += '</li>';
|
||||
$('#embedPhotoModalBodyAlbumList').find('ul').append(albumLink);
|
||||
}
|
||||
$('#embedPhotoModalBodyAlbumDialog').addClass('d-none');
|
||||
$('#embedPhotoModalBodyAlbumListDialog').removeClass('d-none');
|
||||
} else {
|
||||
window.console.log("{{$modalerrorlist}}" + ':' + data['errormsg']);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
'json');
|
||||
};
|
||||
</script>
|
||||
|
||||
<input id="invisible-photos-file-upload" type="file" name="files" style="visibility:hidden;position:absolute;top:-50;left:-50;width:0;height:0;" >
|
||||
|
||||
<div id="profile-photo-content" class="generic-content-wrapper">
|
||||
<div class="section-title-wrapper">
|
||||
<h2>{{$title}}</h2>
|
||||
</div>
|
||||
<div class="section-content-wrapper">
|
||||
{{if $info}}
|
||||
<div class="section-content-warning-wrapper">{{$info}}</div>
|
||||
{{/if}}
|
||||
{{if $existing}}
|
||||
<img class="cover-photo-review" style="max-width: 100%;" src="{{$existing.url}}" alt="{{t('Cover Photo')}}" />
|
||||
{{/if}}
|
||||
<form enctype="multipart/form-data" id="cover-photo-form" action="admin/cover_photo" method="post">
|
||||
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
|
||||
<div id="profile-photo-upload-wrapper">
|
||||
<div id="profile-photo-upload-spinner" class="spinner-wrapper">
|
||||
<div class="spinner m"></div>
|
||||
</div>
|
||||
<!--label id="profile-photo-upload-label" class="form-label" for="profile-photo-upload">{{$lbl_upfile}}</label>
|
||||
<input name="userfile" class="form-input" type="file" id="profile-photo-upload" size="48" / -->
|
||||
<div class="clear"></div>
|
||||
<br>
|
||||
<br>
|
||||
<div id="profile-photo-submit-wrapper">
|
||||
<input type="submit" name="submit" id="profile-photo-submit" value="{{$submit}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<br>
|
||||
<div id="profile-photo-link-select-wrapper">
|
||||
<button id="embed-photo-wrapper" class="btn btn-default btn-primary" title="{{$embedPhotos}}" onclick="initializeEmbedPhotoDialog();return false;">
|
||||
<i id="embed-photo" class="fa fa-file-image-o"></i> {{$select}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$('#invisible-photos-file-upload').fileupload({
|
||||
url: 'admin/cover_photo',
|
||||
dataType: 'json',
|
||||
dropZone: $('#profile-photo-content'),
|
||||
maxChunkSize: 2 * 1024 * 1024,
|
||||
|
||||
add: function(e,data) {
|
||||
data.formData = $('#cover-photo-form').serializeArray();
|
||||
data.submit();
|
||||
$('#profile-photo-upload-spinner').show();
|
||||
},
|
||||
|
||||
done: function(e,data) {
|
||||
$('#profile-photo-upload-spinner').hide();
|
||||
window.location.href = window.location.href + '/use/' + data.result.message;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('#profile-photo-submit').click(function(event) { event.preventDefault(); $('#invisible-photos-file-upload').trigger('click'); return false;});
|
||||
|
||||
</script>
|
||||
|
||||
<div class="modal" id="embedPhotoModal" tabindex="-1" role="dialog" aria-labelledby="embedPhotoLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="embedPhotoModalLabel">{{$embedPhotosModalTitle}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body" id="embedPhotoModalBody" >
|
||||
<div id="embedPhotoModalBodyAlbumListDialog" class="d-none">
|
||||
<div id="embedPhotoModalBodyAlbumList"></div>
|
||||
</div>
|
||||
<div id="embedPhotoModalBodyAlbumDialog" class="d-none"></div>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
48
view/tpl/admin_cropbody.tpl
Normal file
48
view/tpl/admin_cropbody.tpl
Normal file
|
@ -0,0 +1,48 @@
|
|||
<h1>{{$title}}</h1>
|
||||
<p id="cropimage-desc">
|
||||
{{$desc}}
|
||||
</p>
|
||||
<div id="cropimage-wrapper">
|
||||
<img src="{{$image_url}}" id="croppa" class="imgCrop" alt="{{$title}}" />
|
||||
</div>
|
||||
<div id="cropimage-preview-wrapper" >
|
||||
<div id="previewWrap" class="crop-preview d-lg-none" style="height: 300px; width: 300px; max-width: 300px; max-height: 300px; overflow: hidden;"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
|
||||
var image = document.getElementById('croppa');
|
||||
var cropper = new Cropper(image, {
|
||||
aspectRatio: 1 / 1,
|
||||
viewMode: 1,
|
||||
preview: '#profile-photo-wrapper, .crop-preview',
|
||||
crop: function(e) {
|
||||
$( '#x1' ).val(e.detail.x);
|
||||
$( '#y1' ).val(e.detail.y);
|
||||
$( '#x2' ).val(e.detail.x + e.detail.width);
|
||||
$( '#y2' ).val(e.detail.y + e.detail.height);
|
||||
$( '#width' ).val(e.detail.scaleX);
|
||||
$( '#height' ).val(e.detail.scaleY);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<form action="admin/profile_photo/{{$resource}}" id="crop-image-form" method="post" />
|
||||
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
|
||||
|
||||
<input type='hidden' name='profile' value='{{$profile}}'>
|
||||
<input type="hidden" name="cropfinal" value="1" />
|
||||
<input type="hidden" name="xstart" id="x1" />
|
||||
<input type="hidden" name="ystart" id="y1" />
|
||||
<input type="hidden" name="xfinal" id="x2" />
|
||||
<input type="hidden" name="yfinal" id="y2" />
|
||||
<input type="hidden" name="height" id="height" />
|
||||
<input type="hidden" name="width" id="width" />
|
||||
|
||||
<div id="crop-image-submit-wrapper" >
|
||||
<input type="submit" name="submit" value="{{$done}}" />
|
||||
</div>
|
||||
|
||||
</form>
|
47
view/tpl/admin_cropcover.tpl
Executable file
47
view/tpl/admin_cropcover.tpl
Executable file
|
@ -0,0 +1,47 @@
|
|||
<h1>{{$title}}</h1>
|
||||
<p id="cropimage-desc">
|
||||
{{$desc}}
|
||||
</p>
|
||||
<div id="cropimage-wrapper">
|
||||
<img src="{{$image_url}}" id="croppa" class="imgCrop" alt="{{$title}}" />
|
||||
</div>
|
||||
<div id="cropimage-preview-wrapper" >
|
||||
<div id="previewWrap" class="crop-preview" style="width: 320px; height: 116px; max-width: 320px; max-height: 116px; overflow: hidden"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
var image = document.getElementById('croppa');
|
||||
var cropper = new Cropper(image, {
|
||||
aspectRatio: 2.75 / 1,
|
||||
viewMode: 1,
|
||||
preview: '.crop-preview',
|
||||
crop: function(e) {
|
||||
$( '#x1' ).val(e.detail.x);
|
||||
$( '#y1' ).val(e.detail.y);
|
||||
$( '#x2' ).val(e.detail.x + e.detail.width);
|
||||
$( '#y2' ).val(e.detail.y + e.detail.height);
|
||||
$( '#width' ).val(e.detail.scaleX);
|
||||
$( '#height' ).val(e.detail.scaleY);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<form action="admin/cover_photo/{{$resource}}" id="crop-image-form" method="post" />
|
||||
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
|
||||
|
||||
<input type='hidden' name='profile' value='{{$profile}}'>
|
||||
<input type="hidden" name="cropfinal" value="1" />
|
||||
<input type="hidden" name="xstart" id="x1" />
|
||||
<input type="hidden" name="ystart" id="y1" />
|
||||
<input type="hidden" name="xfinal" id="x2" />
|
||||
<input type="hidden" name="yfinal" id="y2" />
|
||||
<input type="hidden" name="height" id="height" />
|
||||
<input type="hidden" name="width" id="width" />
|
||||
|
||||
<div id="crop-image-submit-wrapper" >
|
||||
<input type="submit" name="submit" value="{{$done}}" />
|
||||
</div>
|
||||
|
||||
</form>
|
195
view/tpl/admin_profile_photo.tpl
Normal file
195
view/tpl/admin_profile_photo.tpl
Normal file
|
@ -0,0 +1,195 @@
|
|||
<script src="vendor/blueimp/jquery-file-upload/js/vendor/jquery.ui.widget.js"></script>
|
||||
<script src="vendor/blueimp/jquery-file-upload/js/jquery.iframe-transport.js"></script>
|
||||
<script src="vendor/blueimp/jquery-file-upload/js/jquery.fileupload.js"></script>
|
||||
|
||||
|
||||
<script>
|
||||
var initializeEmbedPhotoDialog = function () {
|
||||
$('.embed-photo-selected-photo').each(function (index) {
|
||||
$(this).removeClass('embed-photo-selected-photo');
|
||||
});
|
||||
getPhotoAlbumList();
|
||||
$('#embedPhotoModalBodyAlbumDialog').off('click');
|
||||
$('#embedPhotoModal').modal('show');
|
||||
};
|
||||
|
||||
var choosePhotoFromAlbum = function (album) {
|
||||
$.post("embedphotos/album/{{$channel_id}}", {name: album},
|
||||
function(data) {
|
||||
if (data['status']) {
|
||||
$('#embedPhotoModalLabel').html("{{$modalchooseimages}}");
|
||||
$('#embedPhotoModalBodyAlbumDialog').html('\
|
||||
<div><div class="nav nav-pills flex-column">\n\
|
||||
<li class="nav-item"><a class="nav-link" href="#" onclick="initializeEmbedPhotoDialog();return false;">\n\
|
||||
<i class="fa fa-chevron-left"></i> \n\
|
||||
{{$modaldiffalbum}}\n\
|
||||
</a>\n\
|
||||
</li>\n\
|
||||
</div><br></div>')
|
||||
$('#embedPhotoModalBodyAlbumDialog').append(data['content']);
|
||||
$('#embedPhotoModalBodyAlbumDialog').click(function (evt) {
|
||||
evt.preventDefault();
|
||||
var image = document.getElementById(evt.target.id);
|
||||
if (typeof($(image).parent()[0]) !== 'undefined') {
|
||||
var imageparent = document.getElementById($(image).parent()[0].id);
|
||||
$(imageparent).toggleClass('embed-photo-selected-photo');
|
||||
var href = $(imageparent).attr('href');
|
||||
$.post("embedphotos/photolink/{{$channel_id}}", {href: href},
|
||||
function(ddata) {
|
||||
if (ddata['status']) {
|
||||
var pf = $('#profile-photo-profiles').val();
|
||||
var prof = ((typeof pf !== 'undefined') ? '?f=&pf=' + pf : '');
|
||||
window.location.href = 'admin/profile_photo/use/' + ddata['resource_id'] + prof;
|
||||
} else {
|
||||
window.console.log("{{$modalerrorlink}}" + ':' + ddata['errormsg']);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
'json');
|
||||
$('#embedPhotoModalBodyAlbumDialog').html('');
|
||||
$('#embedPhotoModalBodyAlbumDialog').off('click');
|
||||
$('#embedPhotoModal').modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
$('#embedPhotoModalBodyAlbumListDialog').addClass('d-none');
|
||||
$('#embedPhotoModalBodyAlbumDialog').removeClass('d-none');
|
||||
} else {
|
||||
window.console.log("{{$modalerroralbum}} " + JSON.stringify(album) + ':' + data['errormsg']);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
'json');
|
||||
};
|
||||
|
||||
var getPhotoAlbumList = function () {
|
||||
$.post("embedphotos/albumlist/{{$channel_id}}", {},
|
||||
function(data) {
|
||||
if (data['status']) {
|
||||
var albums = data['albumlist']; //JSON.parse(data['albumlist']);
|
||||
$('#embedPhotoModalLabel').html("{{$modalchoosealbum}}");
|
||||
$('#embedPhotoModalBodyAlbumList').html('<ul class="nav nav-pills flex-column"></ul>');
|
||||
for(var i=0; i<albums.length; i++) {
|
||||
var albumName = albums[i].text;
|
||||
var jsAlbumName = albums[i].jstext;
|
||||
var albumLink = '<li class="nav-item">';
|
||||
albumLink += '<a class="nav-link" href="#" onclick="choosePhotoFromAlbum(\'' + jsAlbumName + '\'); return false;">' + albumName + '</a>';
|
||||
albumLink += '</li>';
|
||||
$('#embedPhotoModalBodyAlbumList').find('ul').append(albumLink);
|
||||
}
|
||||
$('#embedPhotoModalBodyAlbumDialog').addClass('d-none');
|
||||
$('#embedPhotoModalBodyAlbumListDialog').removeClass('d-none');
|
||||
} else {
|
||||
window.console.log("{{$modalerrorlist}}" + ':' + data['errormsg']);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
'json');
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<input id="invisible-photos-file-upload" type="file" name="files" style="visibility:hidden;position:absolute;top:-50;left:-50;width:0;height:0;" >
|
||||
|
||||
|
||||
<div id="profile-photo-content" class="generic-content-wrapper">
|
||||
<div class="section-title-wrapper">
|
||||
<h2>{{$title}}</h2>
|
||||
</div>
|
||||
<div class="section-content-wrapper">
|
||||
|
||||
<form enctype="multipart/form-data" id="profile-photo-form" action="admin/profile_photo" method="post">
|
||||
<input type='hidden' name='form_security_token' value='{{$form_security_token}}'>
|
||||
|
||||
<div id="profile-photo-upload-wrapper">
|
||||
{{if $info}}
|
||||
<div class="section-content-warning-wrapper">{{$info}}</div>
|
||||
{{/if}}
|
||||
{{if $importfile}}
|
||||
<input type="hidden" name="importfile" value="{{$importfile}}">
|
||||
{{else}}
|
||||
<div id="profile-photo-upload-spinner" class="spinner-wrapper">
|
||||
<div class="spinner m"></div>
|
||||
</div>
|
||||
<!--label id="profile-photo-upload-label" class="form-label" for="profile-photo-upload">{{$lbl_upfile}}</label>
|
||||
<input name="userfile" class="form-input" type="file" id="profile-photo-upload" size="48" / -->
|
||||
{{/if}}
|
||||
<div class="clear"></div>
|
||||
|
||||
|
||||
{{if $single}}
|
||||
<input type="hidden" name="profile" value="{{$profile0.id}}" />
|
||||
{{else}}
|
||||
|
||||
|
||||
|
||||
<label id="profile-photo-profiles-label" class="form-label" for="profile-photo-profiles">{{$lbl_profiles}}</label>
|
||||
<select name="profile" id="profile-photo-profiles" class="form-control" >
|
||||
{{foreach $profiles as $p}}
|
||||
<option value="{{$p.id}}" {{if $p.selected}}selected="selected"{{/if}}>{{$p.name}}</option>
|
||||
{{/foreach}}
|
||||
</select>
|
||||
<div class="clear"></div>
|
||||
<br>
|
||||
<br>
|
||||
{{/if}}
|
||||
|
||||
<div id="profile-photo-submit-wrapper">
|
||||
<input type="submit" name="submit" id="profile-photo-submit" value="{{$submit}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<br>
|
||||
<div id="profile-photo-link-select-wrapper">
|
||||
<button id="embed-photo-wrapper" class="btn btn-default btn-primary" title="{{$embedPhotos}}" onclick="initializeEmbedPhotoDialog();return false;">
|
||||
<i id="embed-photo" class="fa fa-file-image-o"></i> {{$select}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$('#invisible-photos-file-upload').fileupload({
|
||||
url: 'admin/profile_photo',
|
||||
dataType: 'json',
|
||||
dropZone: $('#profile-photo-content'),
|
||||
maxChunkSize: 2 * 1024 * 1024,
|
||||
|
||||
add: function(e,data) {
|
||||
data.formData = $('#profile-photo-form').serializeArray();
|
||||
data.submit();
|
||||
$('#profile-photo-upload-spinner').show();
|
||||
},
|
||||
|
||||
done: function(e,data) {
|
||||
$('#profile-photo-upload-spinner').hide();
|
||||
window.location.href = window.location.href + '/use/' + data.result.message;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$('#profile-photo-submit').click(function(event) { event.preventDefault(); $('#invisible-photos-file-upload').trigger('click'); return false;});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div class="modal" id="embedPhotoModal" tabindex="-1" role="dialog" aria-labelledby="embedPhotoLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="embedPhotoModalLabel">{{$embedPhotosModalTitle}}</h4>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
</div>
|
||||
<div class="modal-body" id="embedPhotoModalBody" >
|
||||
<div id="embedPhotoModalBodyAlbumListDialog" class="d-none">
|
||||
<div id="embedPhotoModalBodyAlbumList"></div>
|
||||
</div>
|
||||
<div id="embedPhotoModalBodyAlbumDialog" class="d-none"></div>
|
||||
</div>
|
||||
</div><!-- /.modal-content -->
|
||||
</div><!-- /.modal-dialog -->
|
||||
</div><!-- /.modal -->
|
|
@ -55,7 +55,6 @@
|
|||
<div id="basic-settings-collapse" class="collapse show" role="tabpanel" aria-labelledby="basic-settings" data-parent="#settings">
|
||||
<div class="section-content-tools-wrapper">
|
||||
{{include file="field_input.tpl" field=$sitename}}
|
||||
{{include file="field_textarea.tpl" field=$banner}}
|
||||
{{include file="field_textarea.tpl" field=$siteinfo}}
|
||||
{{include file="field_textarea.tpl" field=$admininfo}}
|
||||
{{include file="field_input.tpl" field=$reply_address}}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="project-banner" title="{{$project_title}}"><a href="{{$baseurl}}/siteinfo"><img src="{{$project_icon}}" alt="{{$project_title}}"></a></div>
|
||||
<div class="project-banner" title="{{$project_title}}"><a href="{{$baseurl}}/siteinfo"><img src="{{$project_icon}}" alt="{{$project_title}}" class="nav-avatar"></a></div>
|
||||
{{if $nav.login && !$userinfo}}
|
||||
<div class="d-lg-none pt-1 pb-1">
|
||||
{{if $nav.loginmenu.1.4}}
|
||||
|
|
Loading…
Reference in a new issue