File manager - Edit - /home/matthif/www/wp-content/languages/options.tar
Back
layout_single_page.php 0000666 00000002303 15226760542 0011142 0 ustar 00 <?php /** * Single page layout section. * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Customizer\Types\Control; /** * Class Layout_Single_Page */ class Layout_Single_Page extends Base_Layout_Single { /** * Returns the post type. * * @return string */ public function get_post_type() { return 'page'; } /** * @return string */ public function get_cover_selector() { return '.page .nv-post-cover'; } /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { parent::add_controls(); $this->add_control( new Control( 'neve_page_hide_title', [ 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => false, ], [ 'label' => esc_html__( 'Disable Title', 'neve' ), 'section' => $this->section, 'type' => 'neve_toggle_control', 'priority' => 25, ], 'Neve\Customizer\Controls\Checkbox' ) ); } /** * Fuction used for active_callback control property. * * @return bool */ public static function is_cover_layout() { return get_theme_mod( 'neve_page_header_layout' ) === 'cover'; } } elFinderVolumeLocalFileSystem.class.php 0000666 00000136366 15226760542 0014315 0 ustar 00 <?php // Implement similar functionality in PHP 5.2 or 5.3 // http://php.net/manual/class.recursivecallbackfilteriterator.php#110974 if (!class_exists('RecursiveCallbackFilterIterator', false)) { class RecursiveCallbackFilterIterator extends RecursiveFilterIterator { private $callback; public function __construct(RecursiveIterator $iterator, $callback) { $this->callback = $callback; parent::__construct($iterator); } public function accept() { return call_user_func($this->callback, parent::current(), parent::key(), parent::getInnerIterator()); } public function getChildren() { return new self($this->getInnerIterator()->getChildren(), $this->callback); } } } /** * elFinder driver for local filesystem. * * @author Dmitry (dio) Levashov * @author Troex Nevelin **/ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver { /** * Driver id * Must be started from letter and contains [a-z0-9] * Used as part of volume id * * @var string **/ protected $driverId = 'l'; /** * Required to count total archive files size * * @var int **/ protected $archiveSize = 0; /** * Is checking stat owner * * @var boolean */ protected $statOwner = false; /** * Path to quarantine directory * * @var string */ private $quarantine; /** * Constructor * Extend options with required fields * * @author Dmitry (dio) Levashov */ public function __construct() { $this->options['alias'] = ''; // alias to replace root dir name $this->options['dirMode'] = 0755; // new dirs mode $this->options['fileMode'] = 0644; // new files mode $this->options['rootCssClass'] = 'elfinder-navbar-root-local'; $this->options['followSymLinks'] = true; $this->options['detectDirIcon'] = ''; // file name that is detected as a folder icon e.g. '.diricon.png' $this->options['keepTimestamp'] = array('copy', 'move'); // keep timestamp at inner filesystem allowed 'copy', 'move' and 'upload' $this->options['substituteImg'] = true; // support substitute image with dim command $this->options['statCorrector'] = null; // callable to correct stat data `function(&$stat, $path, $statOwner, $volumeDriveInstance){}` if (DIRECTORY_SEPARATOR === '/') { // Linux $this->options['acceptedName'] = '/^[^\.\/\x00][^\/\x00]*$/'; } else { // Windows $this->options['acceptedName'] = '/^[^\.\/\x00\\\:*?"<>|][^\/\x00\\\:*?"<>|]*$/'; } } /*********************************************************************/ /* INIT AND CONFIGURE */ /*********************************************************************/ /** * Prepare driver before mount volume. * Return true if volume is ready. * * @return bool **/ protected function init() { // Normalize directory separator for windows if (DIRECTORY_SEPARATOR !== '/') { foreach (array('path', 'tmbPath', 'tmpPath', 'quarantine') as $key) { if (!empty($this->options[$key])) { $this->options[$key] = str_replace('/', DIRECTORY_SEPARATOR, $this->options[$key]); } } // PHP >= 7.1 Supports UTF-8 path on Windows if (version_compare(PHP_VERSION, '7.1', '>=')) { $this->options['encoding'] = ''; $this->options['locale'] = ''; } } if (!$cwd = getcwd()) { return $this->setError('elFinder LocalVolumeDriver requires a result of getcwd().'); } // detect systemRoot if (!isset($this->options['systemRoot'])) { if ($cwd[0] === DIRECTORY_SEPARATOR || $this->root[0] === DIRECTORY_SEPARATOR) { $this->systemRoot = DIRECTORY_SEPARATOR; } else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $this->root, $m)) { $this->systemRoot = $m[1]; } else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $cwd, $m)) { $this->systemRoot = $m[1]; } } $this->root = $this->getFullPath($this->root, $cwd); if (!empty($this->options['startPath'])) { $this->options['startPath'] = $this->getFullPath($this->options['startPath'], $this->root); } if (is_null($this->options['syncChkAsTs'])) { $this->options['syncChkAsTs'] = true; } if (is_null($this->options['syncCheckFunc'])) { $this->options['syncCheckFunc'] = array($this, 'localFileSystemInotify'); } // check 'statCorrector' if (empty($this->options['statCorrector']) || !is_callable($this->options['statCorrector'])) { $this->options['statCorrector'] = null; } return true; } /** * Configure after successfull mount. * * @return void * @throws elFinderAbortException * @author Dmitry (dio) Levashov */ protected function configure() { $hiddens = array(); $root = $this->stat($this->root); // check thumbnails path if (!empty($this->options['tmbPath'])) { if (strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false) { $hiddens['tmb'] = $this->options['tmbPath']; $this->options['tmbPath'] = $this->_abspath($this->options['tmbPath']); } else { $this->options['tmbPath'] = $this->_normpath($this->options['tmbPath']); } } // check temp path if (!empty($this->options['tmpPath'])) { if (strpos($this->options['tmpPath'], DIRECTORY_SEPARATOR) === false) { $hiddens['temp'] = $this->options['tmpPath']; $this->options['tmpPath'] = $this->_abspath($this->options['tmpPath']); } else { $this->options['tmpPath'] = $this->_normpath($this->options['tmpPath']); } } // check quarantine path $_quarantine = ''; if (!empty($this->options['quarantine'])) { if (strpos($this->options['quarantine'], DIRECTORY_SEPARATOR) === false) { $_quarantine = $this->_abspath($this->options['quarantine']); $this->options['quarantine'] = ''; } else { $this->options['quarantine'] = $this->_normpath($this->options['quarantine']); } } else { $_quarantine = $this->_abspath('.quarantine'); } is_dir($_quarantine) && self::localRmdirRecursive($_quarantine); parent::configure(); // check tmbPath if (!$this->tmbPath && isset($hiddens['tmb'])) { unset($hiddens['tmb']); } // if no thumbnails url - try detect it if ($root['read'] && !$this->tmbURL && $this->URL) { if (strpos($this->tmbPath, $this->root) === 0) { $this->tmbURL = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($this->tmbPath, strlen($this->root) + 1)); if (preg_match("|[^/?&=]$|", $this->tmbURL)) { $this->tmbURL .= '/'; } } } // set $this->tmp by options['tmpPath'] $this->tmp = ''; if (!empty($this->options['tmpPath'])) { if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'], $this->options['dirMode'], true)) && is_writable($this->options['tmpPath'])) { $this->tmp = $this->options['tmpPath']; } else { if (isset($hiddens['temp'])) { unset($hiddens['temp']); } } } if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) { $this->tmp = $tmp; } // check quarantine dir $this->quarantine = ''; if (!empty($this->options['quarantine'])) { if ((is_dir($this->options['quarantine']) || mkdir($this->options['quarantine'], $this->options['dirMode'], true)) && is_writable($this->options['quarantine'])) { $this->quarantine = $this->options['quarantine']; } else { if (isset($hiddens['quarantine'])) { unset($hiddens['quarantine']); } } } else if ($_path = elFinder::getCommonTempPath()) { $this->quarantine = $_path; } if (!$this->quarantine) { if (!$this->tmp) { $this->archivers['extract'] = array(); $this->disabled[] = 'extract'; } else { $this->quarantine = $this->tmp; } } if ($hiddens) { foreach ($hiddens as $hidden) { $this->attributes[] = array( 'pattern' => '~^' . preg_quote(DIRECTORY_SEPARATOR . $hidden, '~') . '$~', 'read' => false, 'write' => false, 'locked' => true, 'hidden' => true ); } } if (!empty($this->options['keepTimestamp'])) { $this->options['keepTimestamp'] = array_flip($this->options['keepTimestamp']); } $this->statOwner = (!empty($this->options['statOwner'])); // enable WinRemoveTailDots plugin on Windows server if (DIRECTORY_SEPARATOR !== '/') { if (!isset($this->options['plugin'])) { $this->options['plugin'] = array(); } $this->options['plugin']['WinRemoveTailDots'] = array('enable' => true); } } /** * Long pooling sync checker * This function require server command `inotifywait` * If `inotifywait` need full path, Please add `define('ELFINER_INOTIFYWAIT_PATH', '/PATH_TO/inotifywait');` into connector.php * * @param string $path * @param int $standby * @param number $compare * * @return number|bool * @throws elFinderAbortException */ public function localFileSystemInotify($path, $standby, $compare) { if (isset($this->sessionCache['localFileSystemInotify_disable'])) { return false; } $path = realpath($path); $mtime = filemtime($path); if (!$mtime) { return false; } if ($mtime != $compare) { return $mtime; } $inotifywait = defined('ELFINER_INOTIFYWAIT_PATH') ? ELFINER_INOTIFYWAIT_PATH : 'inotifywait'; $standby = max(1, intval($standby)); $cmd = $inotifywait . ' ' . escapeshellarg($path) . ' -t ' . $standby . ' -e moved_to,moved_from,move,close_write,delete,delete_self'; $this->procExec($cmd, $o, $r); if ($r === 0) { // changed clearstatcache(); if (file_exists($path)) { $mtime = filemtime($path); // error on busy? return $mtime ? $mtime : time(); } else { // target was removed return 0; } } else if ($r === 2) { // not changed (timeout) return $compare; } // error // cache to $_SESSION $this->sessionCache['localFileSystemInotify_disable'] = true; $this->session->set($this->id, $this->sessionCache); return false; } /*********************************************************************/ /* FS API */ /*********************************************************************/ /*********************** paths/urls *************************/ /** * Return parent directory path * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _dirname($path) { return dirname($path); } /** * Return file name * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _basename($path) { return basename($path); } /** * Join dir name and file name and retur full path * * @param string $dir * @param string $name * * @return string * @author Dmitry (dio) Levashov **/ protected function _joinPath($dir, $name) { $dir = rtrim($dir, DIRECTORY_SEPARATOR); $path = realpath($dir . DIRECTORY_SEPARATOR . $name); // realpath() returns FALSE if the file does not exist if ($path === false || strpos($path, $this->root) !== 0) { if (DIRECTORY_SEPARATOR !== '/') { $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir); $name = str_replace('/', DIRECTORY_SEPARATOR, $name); } // Directory traversal measures if (strpos($dir, '..' . DIRECTORY_SEPARATOR) !== false || substr($dir, -2) == '..') { $dir = $this->root; } if (strpos($name, '..' . DIRECTORY_SEPARATOR) !== false) { $name = basename($name); } $path = $dir . DIRECTORY_SEPARATOR . $name; } return $path; } /** * Return normalized path, this works the same as os.path.normpath() in Python * * @param string $path path * * @return string * @author Troex Nevelin **/ protected function _normpath($path) { if (empty($path)) { return '.'; } $changeSep = (DIRECTORY_SEPARATOR !== '/'); if ($changeSep) { $drive = ''; if (preg_match('/^([a-zA-Z]:)(.*)/', $path, $m)) { $drive = $m[1]; $path = $m[2] ? $m[2] : '/'; } $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); } if (strpos($path, '/') === 0) { $initial_slashes = true; } else { $initial_slashes = false; } if (($initial_slashes) && (strpos($path, '//') === 0) && (strpos($path, '///') === false)) { $initial_slashes = 2; } $initial_slashes = (int)$initial_slashes; $comps = explode('/', $path); $new_comps = array(); foreach ($comps as $comp) { if (in_array($comp, array('', '.'))) { continue; } if (($comp != '..') || (!$initial_slashes && !$new_comps) || ($new_comps && (end($new_comps) == '..'))) { array_push($new_comps, $comp); } elseif ($new_comps) { array_pop($new_comps); } } $comps = $new_comps; $path = implode('/', $comps); if ($initial_slashes) { $path = str_repeat('/', $initial_slashes) . $path; } if ($changeSep) { $path = $drive . str_replace('/', DIRECTORY_SEPARATOR, $path); } return $path ? $path : '.'; } /** * Return file path related to root dir * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _relpath($path) { if ($path === $this->root) { return ''; } else { if (strpos($path, $this->root) === 0) { return ltrim(substr($path, strlen($this->root)), DIRECTORY_SEPARATOR); } else { // for link return $path; } } } /** * Convert path related to root dir into real path * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _abspath($path) { if ($path === DIRECTORY_SEPARATOR) { return $this->root; } else { $path = $this->_normpath($path); if (strpos($path, $this->systemRoot) === 0) { return $path; } else if (DIRECTORY_SEPARATOR !== '/' && preg_match('/^[a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . '/', $path)) { return $path; } else { return $this->_joinPath($this->root, $path); } } } /** * Return fake path started from root dir * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _path($path) { return $this->rootName . ($path == $this->root ? '' : $this->separator . $this->_relpath($path)); } /** * Return true if $path is children of $parent * * @param string $path path to check * @param string $parent parent path * * @return bool * @author Dmitry (dio) Levashov **/ protected function _inpath($path, $parent) { $cwd = getcwd(); $real_path = $this->getFullPath($path, $cwd); $real_parent = $this->getFullPath($parent, $cwd); if ($real_path && $real_parent) { return $real_path === $real_parent || strpos($real_path, rtrim($real_parent, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR) === 0; } return false; } /***************** file stat ********************/ /** * Return stat for given path. * Stat contains following fields: * - (int) size file size in b. required * - (int) ts file modification time in unix time. required * - (string) mime mimetype. required for folders, others - optionally * - (bool) read read permissions. required * - (bool) write write permissions. required * - (bool) locked is object locked. optionally * - (bool) hidden is object hidden. optionally * - (string) alias for symlinks - link target path relative to root path. optionally * - (string) target for symlinks - link target path. optionally * If file does not exists - returns empty array or false. * * @param string $path file path * * @return array|false * @author Dmitry (dio) Levashov **/ protected function _stat($path) { $stat = array(); if (!file_exists($path) && !is_link($path)) { return $stat; } //Verifies the given path is the root or is inside the root. Prevents directory traveral. if (!$this->_inpath($path, $this->root)) { return $stat; } $stat['isowner'] = false; $linkreadable = false; if ($path != $this->root && is_link($path)) { if (!$this->options['followSymLinks']) { return array(); } if (!($target = $this->readlink($path)) || $target == $path) { if (is_null($target)) { $stat = array(); return $stat; } else { $stat['mime'] = 'symlink-broken'; $target = readlink($path); $lstat = lstat($path); $ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']); $linkreadable = !empty($ostat['isowner']); } } $stat['alias'] = $this->_path($target); $stat['target'] = $target; } $readable = is_readable($path); if ($readable) { $size = sprintf('%u', filesize($path)); $stat['ts'] = filemtime($path); if ($this->statOwner) { $fstat = stat($path); $uid = $fstat['uid']; $gid = $fstat['gid']; $stat['perm'] = substr((string)decoct($fstat['mode']), -4); $stat = array_merge($stat, $this->getOwnerStat($uid, $gid)); } } if (($dir = is_dir($path)) && $this->options['detectDirIcon']) { $favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon']; if ($this->URL && file_exists($favicon)) { $stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1)); } } if (!isset($stat['mime'])) { $stat['mime'] = $dir ? 'directory' : $this->mimetype($path); } //logical rights first $stat['read'] = ($linkreadable || $readable) ? null : false; $stat['write'] = is_writable($path) ? null : false; if (is_null($stat['read'])) { if ($dir) { $stat['size'] = 0; } else if (isset($size)) { $stat['size'] = $size; } } if ($this->options['statCorrector']) { call_user_func_array($this->options['statCorrector'], array(&$stat, $path, $this->statOwner, $this)); } return $stat; } /** * Get stat `owner`, `group` and `isowner` by `uid` and `gid` * Sub-fuction of _stat() and _scandir() * * @param integer $uid * @param integer $gid * * @return array stat */ protected function getOwnerStat($uid, $gid) { static $names = null; static $phpuid = null; if (is_null($names)) { $names = array('uid' => array(), 'gid' => array()); } if (is_null($phpuid)) { if (is_callable('posix_getuid')) { $phpuid = posix_getuid(); } else { $phpuid = 0; } } $stat = array(); if ($uid) { $stat['isowner'] = ($phpuid == $uid); if (isset($names['uid'][$uid])) { $stat['owner'] = $names['uid'][$uid]; } else if (is_callable('posix_getpwuid')) { $pwuid = posix_getpwuid($uid); $stat['owner'] = $names['uid'][$uid] = $pwuid['name']; } else { $stat['owner'] = $names['uid'][$uid] = $uid; } } if ($gid) { if (isset($names['gid'][$gid])) { $stat['group'] = $names['gid'][$gid]; } else if (is_callable('posix_getgrgid')) { $grgid = posix_getgrgid($gid); $stat['group'] = $names['gid'][$gid] = $grgid['name']; } else { $stat['group'] = $names['gid'][$gid] = $gid; } } return $stat; } /** * Return true if path is dir and has at least one childs directory * * @param string $path dir path * * @return bool * @author Dmitry (dio) Levashov **/ protected function _subdirs($path) { $dirs = false; if (is_dir($path) && is_readable($path)) { if (class_exists('FilesystemIterator', false)) { $dirItr = new ParentIterator( new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS | FilesystemIterator::CURRENT_AS_SELF | (defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') ? RecursiveDirectoryIterator::FOLLOW_SYMLINKS : 0) ) ); $dirItr->rewind(); if ($dirItr->hasChildren()) { $dirs = true; $name = $dirItr->getSubPathName(); while ($dirItr->valid()) { if (!$this->attr($path . DIRECTORY_SEPARATOR . $name, 'read', null, true)) { $dirs = false; $dirItr->next(); $name = $dirItr->getSubPathName(); continue; } $dirs = true; break; } } } else { $path = strtr($path, array('[' => '\\[', ']' => '\\]', '*' => '\\*', '?' => '\\?')); return (bool)glob(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR); } } return $dirs; } /** * Return object width and height * Usualy used for images, but can be realize for video etc... * * @param string $path file path * @param string $mime file mime type * * @return string * @author Dmitry (dio) Levashov **/ protected function _dimensions($path, $mime) { clearstatcache(); return strpos($mime, 'image') === 0 && is_readable($path) && filesize($path) && ($s = getimagesize($path)) !== false ? $s[0] . 'x' . $s[1] : false; } /******************** file/dir content *********************/ /** * Return symlink target file * * @param string $path link path * * @return string * @author Dmitry (dio) Levashov **/ protected function readlink($path) { if (!($target = readlink($path))) { return null; } if (strpos($target, $this->systemRoot) !== 0) { $target = $this->_joinPath(dirname($path), $target); } if (!file_exists($target)) { return false; } return $target; } /** * Return files list in directory. * * @param string $path dir path * * @return array * @throws elFinderAbortException * @author Dmitry (dio) Levashov */ protected function _scandir($path) { elFinder::checkAborted(); $files = array(); $cache = array(); $dirWritable = is_writable($path); $dirItr = array(); $followSymLinks = $this->options['followSymLinks']; try { $dirItr = new DirectoryIterator($path); } catch (UnexpectedValueException $e) { } foreach ($dirItr as $file) { try { if ($file->isDot()) { continue; } $files[] = $fpath = $file->getPathname(); $br = false; $stat = array(); $stat['isowner'] = false; $linkreadable = false; if ($file->isLink()) { if (!$followSymLinks) { continue; } if (!($target = $this->readlink($fpath)) || $target == $fpath) { if (is_null($target)) { $stat = array(); $br = true; } else { $_path = $fpath; $stat['mime'] = 'symlink-broken'; $target = readlink($_path); $lstat = lstat($_path); $ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']); $linkreadable = !empty($ostat['isowner']); $dir = false; $stat['alias'] = $this->_path($target); $stat['target'] = $target; } } else { $dir = is_dir($target); $stat['alias'] = $this->_path($target); $stat['target'] = $target; $stat['mime'] = $dir ? 'directory' : $this->mimetype($stat['alias']); } } else { if (($dir = $file->isDir()) && $this->options['detectDirIcon']) { $path = $file->getPathname(); $favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon']; if ($this->URL && file_exists($favicon)) { $stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1)); } } $stat['mime'] = $dir ? 'directory' : $this->mimetype($fpath); } $size = sprintf('%u', $file->getSize()); $stat['ts'] = $file->getMTime(); if (!$br) { if ($this->statOwner && !$linkreadable) { $uid = $file->getOwner(); $gid = $file->getGroup(); $stat['perm'] = substr((string)decoct($file->getPerms()), -4); $stat = array_merge($stat, $this->getOwnerStat($uid, $gid)); } //logical rights first $stat['read'] = ($linkreadable || $file->isReadable()) ? null : false; $stat['write'] = $file->isWritable() ? null : false; $stat['locked'] = $dirWritable ? null : true; if (is_null($stat['read'])) { $stat['size'] = $dir ? 0 : $size; } if ($this->options['statCorrector']) { call_user_func_array($this->options['statCorrector'], array(&$stat, $fpath, $this->statOwner, $this)); } } $cache[] = array($fpath, $stat); } catch (RuntimeException $e) { continue; } } if ($cache) { $cache = $this->convEncOut($cache, false); foreach ($cache as $d) { $this->updateCache($d[0], $d[1]); } } return $files; } /** * Open file and return file pointer * * @param string $path file path * @param string $mode * * @return false|resource * @internal param bool $write open file for writing * @author Dmitry (dio) Levashov */ protected function _fopen($path, $mode = 'rb') { return fopen($path, $mode); } /** * Close opened file * * @param resource $fp file pointer * @param string $path * * @return bool * @author Dmitry (dio) Levashov */ protected function _fclose($fp, $path = '') { return (is_resource($fp) && fclose($fp)); } /******************** file/dir manipulations *************************/ /** * Create dir and return created dir path or false on failed * * @param string $path parent dir path * @param string $name new directory name * * @return string|bool * @author Dmitry (dio) Levashov **/ protected function _mkdir($path, $name) { $path = $this->_joinPath($path, $name); if (mkdir($path)) { chmod($path, $this->options['dirMode']); return $path; } return false; } /** * Create file and return it's path or false on failed * * @param string $path parent dir path * @param string $name new file name * * @return string|bool * @author Dmitry (dio) Levashov **/ protected function _mkfile($path, $name) { $path = $this->_joinPath($path, $name); if (($fp = fopen($path, 'w'))) { fclose($fp); chmod($path, $this->options['fileMode']); return $path; } return false; } /** * Create symlink * * @param string $source file to link to * @param string $targetDir folder to create link in * @param string $name symlink name * * @return bool * @author Dmitry (dio) Levashov **/ protected function _symlink($source, $targetDir, $name) { return $this->localFileSystemSymlink($source, $this->_joinPath($targetDir, $name)); } /** * Copy file into another file * * @param string $source source file path * @param string $targetDir target directory path * @param string $name new file name * * @return bool * @author Dmitry (dio) Levashov **/ protected function _copy($source, $targetDir, $name) { $mtime = filemtime($source); $target = $this->_joinPath($targetDir, $name); if ($ret = copy($source, $target)) { isset($this->options['keepTimestamp']['copy']) && $mtime && touch($target, $mtime); } return $ret; } /** * Move file into another parent dir. * Return new file path or false. * * @param string $source source file path * @param $targetDir * @param string $name file name * * @return bool|string * @internal param string $target target dir path * @author Dmitry (dio) Levashov */ protected function _move($source, $targetDir, $name) { $mtime = filemtime($source); $target = $this->_joinPath($targetDir, $name); if ($ret = rename($source, $target) ? $target : false) { isset($this->options['keepTimestamp']['move']) && $mtime && touch($target, $mtime); } return $ret; } /** * Remove file * * @param string $path file path * * @return bool * @author Dmitry (dio) Levashov **/ protected function _unlink($path) { return is_file($path) && unlink($path); } /** * Remove dir * * @param string $path dir path * * @return bool * @author Dmitry (dio) Levashov **/ protected function _rmdir($path) { return rmdir($path); } /** * Create new file and write into it from file pointer. * Return new file path or false on error. * * @param resource $fp file pointer * @param string $dir target dir path * @param string $name file name * @param array $stat file stat (required by some virtual fs) * * @return bool|string * @author Dmitry (dio) Levashov **/ protected function _save($fp, $dir, $name, $stat) { $path = $this->_joinPath($dir, $name); $meta = stream_get_meta_data($fp); $uri = isset($meta['uri']) ? $meta['uri'] : ''; if ($uri && !preg_match('#^[a-zA-Z0-9]+://#', $uri) && !is_link($uri)) { fclose($fp); $mtime = filemtime($uri); $isCmdPaste = ($this->ARGS['cmd'] === 'paste'); $isCmdCopy = ($isCmdPaste && empty($this->ARGS['cut'])); if (($isCmdCopy || !rename($uri, $path)) && !copy($uri, $path)) { return false; } // keep timestamp on upload if ($mtime && $this->ARGS['cmd'] === 'upload') { touch($path, isset($this->options['keepTimestamp']['upload']) ? $mtime : time()); } } else { if (file_put_contents($path, $fp, LOCK_EX) === false) { return false; } } chmod($path, $this->options['fileMode']); return $path; } /** * Get file contents * * @param string $path file path * * @return string|false * @author Dmitry (dio) Levashov **/ protected function _getContents($path) { return file_get_contents($path); } /** * Write a string to a file * * @param string $path file path * @param string $content new file content * * @return bool * @author Dmitry (dio) Levashov **/ protected function _filePutContents($path, $content) { return (file_put_contents($path, $content, LOCK_EX) !== false); } /** * Detect available archivers * * @return void * @throws elFinderAbortException */ protected function _checkArchivers() { $this->archivers = $this->getArchivers(); return; } /** * chmod availability * * @param string $path * @param string $mode * * @return bool */ protected function _chmod($path, $mode) { $modeOct = is_string($mode) ? octdec($mode) : octdec(sprintf("%04o", $mode)); return chmod($path, $modeOct); } /** * Recursive symlinks search * * @param string $path file/dir path * * @return bool * @throws Exception * @author Dmitry (dio) Levashov */ protected function _findSymlinks($path) { return self::localFindSymlinks($path); } /** * Extract files from archive * * @param string $path archive path * @param array $arc archiver command and arguments (same as in $this->archivers) * * @return array|string|boolean * @throws elFinderAbortException * @author Dmitry (dio) Levashov, * @author Alexey Sukhotin */ protected function _extract($path, $arc) { if ($this->quarantine) { $dir = $this->quarantine . DIRECTORY_SEPARATOR . md5(basename($path) . mt_rand()); $archive = (isset($arc['toSpec']) || $arc['cmd'] === 'phpfunction') ? '' : $dir . DIRECTORY_SEPARATOR . basename($path); if (!mkdir($dir)) { return false; } // insurance unexpected shutdown register_shutdown_function(array($this, 'rmdirRecursive'), realpath($dir)); chmod($dir, 0777); // copy in quarantine if (!is_readable($path) || ($archive && !copy($path, $archive))) { return false; } // extract in quarantine try { $this->unpackArchive($path, $arc, $archive ? true : $dir); } catch(Exception $e) { return $this->setError($e->getMessage()); } // get files list try { $ls = self::localScandir($dir); } catch (Exception $e) { return false; } // no files - extract error ? if (empty($ls)) { return false; } $this->archiveSize = 0; // find symlinks and check extracted items $checkRes = $this->checkExtractItems($dir); if ($checkRes['symlinks']) { self::localRmdirRecursive($dir); return $this->setError(array_merge($this->error, array(elFinder::ERROR_ARC_SYMLINKS))); } $this->archiveSize = $checkRes['totalSize']; if ($checkRes['rmNames']) { foreach ($checkRes['rmNames'] as $name) { $this->addError(elFinder::ERROR_SAVE, $name); } } // check max files size if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) { $this->delTree($dir); return $this->setError(elFinder::ERROR_ARC_MAXSIZE); } $extractTo = $this->extractToNewdir; // 'auto', ture or false // archive contains one item - extract in archive dir $name = ''; $src = $dir . DIRECTORY_SEPARATOR . $ls[0]; if (($extractTo === 'auto' || !$extractTo) && count($ls) === 1 && is_file($src)) { $name = $ls[0]; } else if ($extractTo === 'auto' || $extractTo) { // for several files - create new directory // create unique name for directory $src = $dir; $splits = elFinder::splitFileExtention(basename($path)); $name = $splits[0]; $test = dirname($path) . DIRECTORY_SEPARATOR . $name; if (file_exists($test) || is_link($test)) { $name = $this->uniqueName(dirname($path), $name, '-', false); } } if ($name !== '') { $result = dirname($path) . DIRECTORY_SEPARATOR . $name; if (!rename($src, $result)) { $this->delTree($dir); return false; } } else { $dstDir = dirname($path); $result = array(); foreach ($ls as $name) { $target = $dstDir . DIRECTORY_SEPARATOR . $name; if (self::localMoveRecursive($dir . DIRECTORY_SEPARATOR . $name, $target, true, $this->options['copyJoin'])) { $result[] = $target; } } if (!$result) { $this->delTree($dir); return false; } } is_dir($dir) && $this->delTree($dir); return (is_array($result) || file_exists($result)) ? $result : false; } //TODO: Add return statement here return false; } /** * Create archive and return its path * * @param string $dir target dir * @param array $files files names list * @param string $name archive name * @param array $arc archiver options * * @return string|bool * @throws elFinderAbortException * @author Dmitry (dio) Levashov, * @author Alexey Sukhotin */ protected function _archive($dir, $files, $name, $arc) { return $this->makeArchive($dir, $files, $name, $arc); } /******************** Over write functions *************************/ /** * File path of local server side work file path * * @param string $path * * @return string * @author Naoki Sawada */ protected function getWorkFile($path) { return $path; } /** * Delete dirctory trees * * @param string $localpath path need convert encoding to server encoding * * @return boolean * @throws elFinderAbortException * @author Naoki Sawada */ protected function delTree($localpath) { return $this->rmdirRecursive($localpath); } /** * Return fileinfo based on filename * For item ID based path file system * Please override if needed on each drivers * * @param string $path file cache * * @return array|boolean false */ protected function isNameExists($path) { $exists = file_exists($this->convEncIn($path)); // restore locale $this->convEncOut(); return $exists ? $this->stat($path) : false; } /******************** Over write (Optimized) functions *************************/ /** * Recursive files search * * @param string $path dir path * @param string $q search string * @param array $mimes * * @return array * @throws elFinderAbortException * @author Dmitry (dio) Levashov * @author Naoki Sawada */ protected function doSearch($path, $q, $mimes) { if (!empty($this->doSearchCurrentQuery['matchMethod']) || $this->encoding || !class_exists('FilesystemIterator', false)) { // has custom match method or non UTF-8, use elFinderVolumeDriver::doSearch() return parent::doSearch($path, $q, $mimes); } $result = array(); $timeout = $this->options['searchTimeout'] ? $this->searchStart + $this->options['searchTimeout'] : 0; if ($timeout && $timeout < time()) { $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($path))); return $result; } elFinder::extendTimeLimit($this->options['searchTimeout'] + 30); $match = array(); try { $iterator = new RecursiveIteratorIterator( new RecursiveCallbackFilterIterator( new RecursiveDirectoryIterator($path, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::SKIP_DOTS | ((defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') && $this->options['followSymLinks']) ? RecursiveDirectoryIterator::FOLLOW_SYMLINKS : 0) ), array($this, 'localFileSystemSearchIteratorFilter') ), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD ); foreach ($iterator as $key => $node) { if ($timeout && ($this->error || $timeout < time())) { !$this->error && $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($node->getPath))); break; } if ($node->isDir()) { if ($this->stripos($node->getFilename(), $q) !== false) { $match[] = $key; } } else { $match[] = $key; } } } catch (Exception $e) { } if ($match) { foreach ($match as $p) { if ($timeout && ($this->error || $timeout < time())) { !$this->error && $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode(dirname($p)))); break; } $stat = $this->stat($p); if (!$stat) { // invalid links continue; } if (!empty($stat['hidden']) || !$this->mimeAccepted($stat['mime'], $mimes)) { continue; } if ((!$mimes || $stat['mime'] !== 'directory')) { $stat['path'] = $this->path($stat['hash']); if ($this->URL && !isset($stat['url'])) { $_path = str_replace(DIRECTORY_SEPARATOR, '/', substr($p, strlen($this->root) + 1)); $stat['url'] = $this->URL . str_replace('%2F', '/', rawurlencode($_path)); } $result[] = $stat; } } } return $result; } /******************** Original local functions ************************ * * @param $file * @param $key * @param $iterator * * @return bool */ public function localFileSystemSearchIteratorFilter($file, $key, $iterator) { /* @var FilesystemIterator $file */ /* @var RecursiveDirectoryIterator $iterator */ $name = $file->getFilename(); if ($this->doSearchCurrentQuery['excludes']) { foreach ($this->doSearchCurrentQuery['excludes'] as $exclude) { if ($this->stripos($name, $exclude) !== false) { return false; } } } if ($iterator->hasChildren()) { if ($this->options['searchExDirReg'] && preg_match($this->options['searchExDirReg'], $key)) { return false; } return (bool)$this->attr($key, 'read', null, true); } return ($this->stripos($name, $this->doSearchCurrentQuery['q']) === false) ? false : true; } /** * Creates a symbolic link * * @param string $target The target * @param string $link The link * * @return boolean ( result of symlink() ) */ protected function localFileSystemSymlink($target, $link) { $res = false; if (function_exists('symlink') and is_callable('symlink')) { $errlev = error_reporting(); error_reporting($errlev ^ E_WARNING); if ($res = symlink(realpath($target), $link)) { $res = is_readable($link); } error_reporting($errlev); } return $res; } } // END class layout_container.php 0000666 00000012241 15226760542 0010651 0 ustar 00 <?php /** * Container layout section. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 20/08/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Section; use Neve\Customizer\Defaults\Layout; use Neve\Core\Settings\Config; /** * Class Layout_Container * * @package Neve\Customizer\Options */ class Layout_Container extends Base_Customizer { use Layout; /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { $this->section_container(); $this->control_container_width(); $this->control_vertical_spacing(); $this->control_container_style(); } /** * Add customize section */ private function section_container() { $this->add_section( new Section( 'neve_container', array( 'priority' => 25, 'title' => esc_html__( 'Container', 'neve' ), 'panel' => 'neve_layout', ) ) ); } /** * Add container width control */ private function control_container_width() { $this->add_control( new Control( 'neve_container_width', [ 'sanitize_callback' => 'neve_sanitize_range_value', 'transport' => $this->selective_refresh, 'default' => '{ "mobile": 748, "tablet": 992, "desktop": 1170 }', ], [ 'label' => esc_html__( 'Container width', 'neve' ), 'section' => 'neve_container', 'type' => 'neve_responsive_range_control', 'input_attrs' => [ 'min' => 200, 'max' => 2000, 'units' => [ 'px' ], 'defaultVal' => [ 'mobile' => 748, 'tablet' => 992, 'desktop' => 1170, 'suffix' => [ 'mobile' => 'px', 'tablet' => 'px', 'desktop' => 'px', ], ], ], 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'selector' => 'body', 'vars' => '--container', 'responsive' => true, 'suffix' => 'px', ], ], 'priority' => 25, ], '\Neve\Customizer\Controls\React\Responsive_Range' ) ); } /** * Add vertical spacing control */ private function control_vertical_spacing() { $this->add_control( new Control( Config::MODS_CONTENT_VSPACING, [ 'default' => $this->content_vspacing_default(), 'transport' => $this->selective_refresh, ], [ 'label' => __( 'Content Vertical Spacing', 'neve' ), 'sanitize_callback' => [ $this, 'sanitize_spacing_array' ], 'section' => 'neve_container', 'input_attrs' => [ 'units' => [ 'px', 'vh' ], 'axis' => 'vertical', ], 'default' => $this->content_vspacing_default(), 'priority' => 26, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--c-vspace', 'selector' => 'body.single:not(.single-product), body.page', 'responsive' => true, 'fallback' => '', ], 'directional' => true, ], ], '\Neve\Customizer\Controls\React\Spacing' ) ); } /** * Add container style controls */ private function control_container_style() { $container_style_controls = array( 'neve_default_container_style' => array( 'priority' => 30, 'label' => __( 'Default Container Style', 'neve' ), ), 'neve_blog_archive_container_style' => array( 'priority' => 35, 'label' => __( 'Blog / Archive Container Style', 'neve' ), ), 'neve_single_post_container_style' => array( 'priority' => 40, 'label' => __( 'Single Post Container Style', 'neve' ), ), ); if ( class_exists( 'WooCommerce', false ) ) { $container_style_controls = array_merge( $container_style_controls, array( 'neve_shop_archive_container_style' => array( 'priority' => 45, 'label' => __( 'Shop / Archive Container Style', 'neve' ), ), 'neve_single_product_container_style' => array( 'priority' => 50, 'label' => __( 'Single Product Container Style', 'neve' ), ), ) ); } /** * Filters the container style controls. * * @param array $container_style_controls Container style controls. * * @since 3.1.0 */ $container_style_controls = apply_filters( 'neve_container_style_filter', $container_style_controls ); foreach ( $container_style_controls as $control_id => $control ) { $this->add_control( new Control( $control_id, array( 'sanitize_callback' => 'neve_sanitize_container_layout', 'transport' => $this->selective_refresh, 'default' => 'contained', ), array( 'label' => $control['label'], 'section' => 'neve_container', 'type' => 'select', 'priority' => $control['priority'], 'choices' => array( 'contained' => __( 'Contained', 'neve' ), 'full-width' => __( 'Full Width', 'neve' ), ), ) ) ); } } } base_layout_single.php 0000666 00000050365 15226760542 0011153 0 ustar 00 <?php /** * Common functionalities for pages and posts. * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Defaults\Layout; use Neve\Customizer\Defaults\Single_Post; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Section; use Neve\Core\Settings\Config; /** * Class Base_Layout_Single * * @package Neve\Customizer\Options */ abstract class Base_Layout_Single extends Base_Customizer { use Single_Post; use Layout; /** * Post type slug * * @var string */ private $post_type; /** * Controls section * * @var string */ public $section; /** * Cover selector * * @var string */ private $cover_selector; /** * Get the value for the $post_type. * * @return mixed */ abstract public function get_post_type(); /** * Get the value for the $post_type. * * @return mixed */ abstract public function get_cover_selector(); /** * Base_Layout_Single constructor. */ public function __construct() { $this->post_type = $this->get_post_type(); $this->cover_selector = $this->get_cover_selector(); $this->section = 'neve_single_' . $this->post_type . '_layout'; } /** * Get the label for sections. */ private function get_section_label() { $labels = [ 'post' => esc_html__( 'Single Post', 'neve' ), 'page' => esc_html__( 'Page', 'neve' ), ]; if ( array_key_exists( $this->post_type, $labels ) ) { return $labels[ $this->post_type ]; } return ''; } /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { $this->create_section(); $this->add_header_layout_subsection(); $this->add_header_layout_controls(); $this->content_vspacing(); } /** * Create the section */ private function create_section() { $this->add_section( new Section( 'neve_single_' . $this->post_type . '_layout', [ 'priority' => 40, 'title' => $this->get_section_label(), 'panel' => 'neve_layout', ] ) ); } /** * Add header layout accordion. */ private function add_header_layout_subsection() { $this->add_control( new Control( 'neve_' . $this->post_type . '_header_layout_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'Header Layout', 'neve' ), 'section' => $this->section, 'priority' => 5, 'class' => 'header_layout-accordion', 'expanded' => true, 'accordion' => true, 'controls_to_wrap' => 15, ], 'Neve\Customizer\Controls\Heading' ) ); } /** * Add controls for header layout. */ private function add_header_layout_controls() { $this->add_control( new Control( 'neve_' . $this->post_type . '_header_layout', [ 'sanitize_callback' => 'wp_filter_nohtml_kses', 'default' => 'normal', ], [ 'section' => $this->section, 'priority' => 10, 'choices' => [ 'normal' => [ 'name' => esc_html__( 'Normal', 'neve' ), 'image' => 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODUiIGhlaWdodD0iMTE4IiB2aWV3Qm94PSIwIDAgODUgMTE4IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogICAgPHJlY3QgeD0iMi4yNSIgeT0iMi40NjM4NyIgd2lkdGg9IjgwIiBoZWlnaHQ9IjExMyIgZmlsbD0id2hpdGUiLz4KICAgIDxyZWN0IHg9IjE3LjI1IiB5PSIxNC42MDQ1IiB3aWR0aD0iNTAiIGhlaWdodD0iMzQuNTUzNyIgZmlsbD0iIzc4QjZGRiIgZmlsbC1vcGFjaXR5PSIwLjQiLz4KICAgIDxsaW5lIHgxPSIxNy4yNSIgeTE9IjYyLjY5MjQiIHgyPSI2Ny4wNzkyIiB5Mj0iNjIuNjkyNCIgc3Ryb2tlPSIjQzRDNEM0IiBzdHJva2Utd2lkdGg9IjIiLz4KICAgIDxsaW5lIHgxPSIxNy4yNSIgeTE9IjY3Ljc2OTUiIHgyPSIyNS4yNSIgeTI9IjY3Ljc2OTUiIHN0cm9rZT0iI0M0QzRDNCIgc3Ryb2tlLXdpZHRoPSIyIi8+CiAgICA8bGluZSB4MT0iMTcuMjUiIHkxPSI1Ny40OTcxIiB4Mj0iNTEuMDA1MyIgeTI9IjU3LjQ5NzEiIHN0cm9rZT0iI0M0QzRDNCIgc3Ryb2tlLXdpZHRoPSIyIi8+CiAgICA8bGluZSB4MT0iMTcuMjUiIHkxPSI4Ny4zODA5IiB4Mj0iNjcuMDc5MiIgeTI9Ijg3LjM4MDkiIHN0cm9rZT0iI0M0QzRDNCIgc3Ryb2tlLXdpZHRoPSIyIi8+CiAgICA8bGluZSB4MT0iMTcuMjUiIHkxPSI5Mi41NzYyIiB4Mj0iNjcuMDc5MiIgeTI9IjkyLjU3NjIiIHN0cm9rZT0iI0M0QzRDNCIgc3Ryb2tlLXdpZHRoPSIyIi8+CiAgICA8bGluZSB4MT0iMTcuMjUiIHkxPSI5OC4wNjE1IiB4Mj0iNjcuMDc5MiIgeTI9Ijk4LjA2MTUiIHN0cm9rZT0iI0M0QzRDNCIgc3Ryb2tlLXdpZHRoPSIyIi8+Cjwvc3ZnPgo=', ], 'cover' => [ 'name' => esc_html__( 'Cover', 'neve' ), 'image' => 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iODYiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgODYgMTIwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogICAgPHJlY3QgeD0iMyIgeT0iMy40NjM4NyIgd2lkdGg9IjgwIiBoZWlnaHQ9IjExMyIgZmlsbD0id2hpdGUiLz4KICAgIDxyZWN0IHg9IjMiIHk9IjMuNDYzODciIHdpZHRoPSI4MCIgaGVpZ2h0PSI1MS4zNjM2IiBmaWxsPSIjNzhCNkZGIiBmaWxsLW9wYWNpdHk9IjAuNCIvPgogICAgPGxpbmUgeDE9IjE5IiB5MT0iNjcuNDI4NyIgeDI9IjY4LjgyOTIiIHkyPSI2Ny40Mjg3IiBzdHJva2U9IiNDNEM0QzQiIHN0cm9rZS13aWR0aD0iMiIvPgogICAgPGxpbmUgeDE9IjE5IiB5MT0iODMuNzExOSIgeDI9IjY4LjgyOTIiIHkyPSI4My43MTE5IiBzdHJva2U9IiNDNEM0QzQiIHN0cm9rZS13aWR0aD0iMiIvPgogICAgPGxpbmUgeDE9IjE5IiB5MT0iNzIuNjI0IiB4Mj0iNjguODI5MiIgeTI9IjcyLjYyNCIgc3Ryb2tlPSIjQzRDNEM0IiBzdHJva2Utd2lkdGg9IjIiLz4KICAgIDxsaW5lIHgxPSIxOSIgeTE9Ijg4LjkwNzIiIHgyPSI2OC44MjkyIiB5Mj0iODguOTA3MiIgc3Ryb2tlPSIjQzRDNEM0IiBzdHJva2Utd2lkdGg9IjIiLz4KICAgIDxsaW5lIHgxPSIxOSIgeTE9Ijc4LjEwODQiIHgyPSI2OC44MjkyIiB5Mj0iNzguMTA4NCIgc3Ryb2tlPSIjQzRDNEM0IiBzdHJva2Utd2lkdGg9IjIiLz4KICAgIDxsaW5lIHgxPSIxOSIgeTE9Ijk0LjM5MjYiIHgyPSI2OC44MjkyIiB5Mj0iOTQuMzkyNiIgc3Ryb2tlPSIjQzRDNEM0IiBzdHJva2Utd2lkdGg9IjIiLz4KICAgIDxsaW5lIHgxPSIxOSIgeTE9IjgzLjcxMTkiIHgyPSI0OCIgeTI9IjgzLjcxMTkiIHN0cm9rZT0iI0M0QzRDNCIgc3Ryb2tlLXdpZHRoPSIyIi8+CiAgICA8bGluZSB4MT0iMTkiIHkxPSI5OS45OTYxIiB4Mj0iNDgiIHkyPSI5OS45OTYxIiBzdHJva2U9IiNDNEM0QzQiIHN0cm9rZS13aWR0aD0iMiIvPgogICAgPGxpbmUgeDE9IjE5IiB5MT0iNDQuNDg5MyIgeDI9IjUyLjc1NTMiIHkyPSI0NC40ODkzIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz4KICAgIDxsaW5lIHgxPSIxOSIgeTE9IjM4Ljg4NTciIHgyPSI2OSIgeTI9IjM4Ljg4NTciIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIvPgogICAgPHJlY3QgeD0iMS41IiB5PSIxLjk2Mzg3IiB3aWR0aD0iODMiIGhlaWdodD0iMTE2IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjMiLz4KPC9zdmc+Cg==', ], ], ], '\Neve\Customizer\Controls\React\Radio_Image' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_cover_height', [ 'sanitize_callback' => 'neve_sanitize_range_value', 'transport' => $this->selective_refresh, 'default' => '{ "mobile": 250, "tablet": 320, "desktop": 400 }', ], [ 'label' => esc_html__( 'Cover height', 'neve' ), 'section' => $this->section, 'type' => 'neve_responsive_range_control', 'input_attrs' => [ 'max' => 700, 'units' => [ 'px', 'vh', 'em', 'rem' ], 'defaultVal' => [ 'mobile' => 250, 'tablet' => 320, 'desktop' => 400, 'suffix' => [ 'mobile' => 'px', 'tablet' => 'px', 'desktop' => 'px', ], ], ], 'priority' => 15, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'responsive' => true, 'vars' => '--height', 'selector' => $this->cover_selector, 'suffix' => 'px', ], ], 'active_callback' => [ $this, 'is_cover_layout' ], ], '\Neve\Customizer\Controls\React\Responsive_Range' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_cover_padding', [ 'sanitize_callback' => [ $this, 'sanitize_spacing_array' ], 'transport' => $this->selective_refresh, 'default' => $this->padding_default( 'cover' ), ], [ 'label' => esc_html__( 'Cover padding', 'neve' ), 'section' => $this->section, 'input_attrs' => [ 'units' => [ 'px', 'em', 'rem' ], 'min' => 0, ], 'default' => $this->padding_default( 'cover' ), 'priority' => 20, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => array( 'vars' => '--padding', 'selector' => $this->cover_selector, 'responsive' => true, ), ], 'active_callback' => [ $this, 'is_cover_layout' ], ], '\Neve\Customizer\Controls\React\Spacing' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_title_alignment', [ 'sanitize_callback' => 'neve_sanitize_alignment', 'transport' => $this->selective_refresh, 'default' => self::post_title_alignment(), ], [ 'label' => esc_html__( 'Title Alignment', 'neve' ), 'section' => $this->section, 'priority' => 30, 'choices' => [ 'left' => [ 'tooltip' => esc_html__( 'Left', 'neve' ), 'icon' => 'editor-alignleft', ], 'center' => [ 'tooltip' => esc_html__( 'Center', 'neve' ), 'icon' => 'editor-aligncenter', ], 'right' => [ 'tooltip' => esc_html__( 'Right', 'neve' ), 'icon' => 'editor-alignright', ], ], 'show_labels' => true, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => [ '--textalign', '--justify', ], 'valueRemap' => [ '--justify' => [ 'left' => 'flex-start', 'center' => 'center', 'right' => 'flex-end', ], ], 'responsive' => true, 'selector' => $this->cover_selector . ',' . $this->cover_selector . ' .container, ' . ( $this->post_type === 'post' ? '.entry-header' : '.nv-page-title-wrap' ), ], ], 'active_callback' => $this->post_type === 'post' ? '__return_true' : function() { return ! get_theme_mod( 'neve_page_hide_title', false ); }, ], '\Neve\Customizer\Controls\React\Responsive_Radio_Buttons' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_title_position', [ 'sanitize_callback' => 'neve_sanitize_position', 'transport' => $this->selective_refresh, 'default' => [ 'mobile' => 'center', 'tablet' => 'center', 'desktop' => 'center', ], ], [ 'label' => esc_html__( 'Title Position', 'neve' ), 'section' => $this->section, 'priority' => 35, 'choices' => [ 'flex-start' => [ 'tooltip' => esc_html__( 'Top', 'neve' ), 'icon' => 'arrow-up', ], 'center' => [ 'tooltip' => esc_html__( 'Middle', 'neve' ), 'icon' => 'sort', ], 'flex-end' => [ 'tooltip' => esc_html__( 'Bottom', 'neve' ), 'icon' => 'arrow-down', ], ], 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--valign', 'responsive' => true, 'selector' => $this->cover_selector, ], ], 'show_labels' => true, 'active_callback' => function() { return $this->post_type === 'post' ? $this->is_cover_layout() : $this->is_cover_layout() && ! get_theme_mod( 'neve_page_hide_title', false ); }, ], '\Neve\Customizer\Controls\React\Responsive_Radio_Buttons' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_cover_background_color', [ 'sanitize_callback' => 'neve_sanitize_colors', 'default' => 'var(--nv-dark-bg)', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Overlay color', 'neve' ), 'section' => $this->section, 'priority' => 45, 'input_attrs' => [ 'allow_gradient' => true, ], 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => array( 'vars' => '--bgcolor', 'selector' => $this->cover_selector . ' .nv-overlay', ), ], 'active_callback' => [ $this, 'is_cover_layout' ], ], 'Neve\Customizer\Controls\React\Color' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_cover_text_color', [ 'sanitize_callback' => 'neve_sanitize_colors', 'default' => 'var(--nv-text-dark-bg)', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Text color', 'neve' ), 'section' => $this->section, 'priority' => 50, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--color', 'selector' => $this->cover_selector . ' .nv-title-meta-wrap', ], ], 'active_callback' => function() { return $this->post_type === 'post' ? $this->is_cover_layout() : $this->is_cover_layout() && ! get_theme_mod( 'neve_page_hide_title', false ); }, ], 'Neve\Customizer\Controls\React\Color' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_cover_overlay_opacity', [ 'sanitize_callback' => 'neve_sanitize_range_value', 'transport' => $this->selective_refresh, 'default' => 50, ], [ 'label' => esc_html__( 'Overlay opacity', 'neve' ) . '(%)', 'section' => $this->section, 'input_attrs' => [ 'min' => 0, 'max' => 100, 'step' => 1, 'defaultVal' => 50, ], 'priority' => 55, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--opacity', 'selector' => $this->cover_selector . ' .nv-overlay', ], ], 'active_callback' => [ $this, 'is_cover_layout' ], ], 'Neve\Customizer\Controls\React\Range' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_cover_hide_thumbnail', [ 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => false, ], [ 'label' => esc_html__( 'Hide featured image', 'neve' ), 'section' => $this->section, 'type' => 'neve_toggle_control', 'priority' => 60, 'active_callback' => [ $this, 'is_cover_layout' ], ], 'Neve\Customizer\Controls\Checkbox' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_cover_blend_mode', [ 'default' => 'normal', 'sanitize_callback' => 'neve_sanitize_blend_mode', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Blend mode', 'neve' ), 'section' => $this->section, 'priority' => 65, 'type' => 'select', 'choices' => [ 'normal' => esc_html__( 'Normal', 'neve' ), 'multiply' => esc_html__( 'Multiply', 'neve' ), 'screen' => esc_html__( 'Screen', 'neve' ), 'overlay' => esc_html__( 'Overlay', 'neve' ), 'darken' => esc_html__( 'Darken', 'neve' ), 'lighten' => esc_html__( 'Lighten', 'neve' ), 'color-dodge' => esc_html__( 'Color Dodge', 'neve' ), 'saturation' => esc_html__( 'Saturation', 'neve' ), 'color' => esc_html__( 'Color', 'neve' ), 'difference' => esc_html__( 'Difference', 'neve' ), 'exclusion' => esc_html__( 'Exclusion', 'neve' ), 'hue' => esc_html__( 'Hue', 'neve' ), 'luminosity' => esc_html__( 'Luminosity', 'neve' ), ], 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--blendmode', 'selector' => $this->cover_selector . ' .nv-overlay', ], ], 'active_callback' => [ $this, 'is_cover_layout' ], ] ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_cover_container', [ 'default' => 'contained', 'sanitize_callback' => 'neve_sanitize_container_layout', ], [ 'label' => esc_html__( 'Cover container', 'neve' ), 'section' => $this->section, 'priority' => 70, 'type' => 'select', 'choices' => [ 'contained' => esc_html__( 'Contained', 'neve' ), 'full-width' => esc_html__( 'Full width', 'neve' ), ], 'active_callback' => function() { return $this->post_type === 'post' ? $this->is_cover_layout() : $this->is_cover_layout() && ! get_theme_mod( 'neve_page_hide_title', false ); }, ] ) ); $this->add_boxed_layout_controls( $this->post_type . '_cover_title', [ 'priority' => 75, 'section' => $this->section, 'has_text_color' => false, 'padding_default' => $this->padding_default( 'cover' ), 'background_default' => 'var(--nv-dark-bg)', 'boxed_selector' => $this->cover_selector . ' .nv-is-boxed.nv-title-meta-wrap', 'toggle_active_callback' => function() { return $this->post_type === 'post' ? $this->is_cover_layout() : $this->is_cover_layout() && ! get_theme_mod( 'neve_page_hide_title', false ); }, 'active_callback' => function() { $is_cover = $this->post_type === 'post' ? $this->is_cover_layout() : $this->is_cover_layout() && ! get_theme_mod( 'neve_page_hide_title', false ); return $is_cover && get_theme_mod( 'neve_' . $this->post_type . '_cover_title_boxed_layout', false ); }, ] ); } /** * Add content spacing control. */ private function content_vspacing() { $this->add_control( new Control( 'neve_' . $this->post_type . '_page_settings_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'Page', 'neve' ) . ' ' . esc_html__( 'Settings', 'neve' ), 'section' => $this->section, 'priority' => 90, 'class' => 'page-settings-accordion', 'expanded' => false, 'accordion' => true, 'controls_to_wrap' => 2, ], 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_' . $this->post_type . '_inherit_vspacing', [ 'sanitize_callback' => 'neve_sanitize_vspace_type', 'default' => 'inherit', ], [ 'label' => esc_html__( 'Content Vertical Spacing', 'neve' ), 'section' => $this->section, 'priority' => 95, 'choices' => [ 'inherit' => [ 'tooltip' => esc_html__( 'Inherit', 'neve' ), 'icon' => 'text', ], 'specific' => [ 'tooltip' => esc_html__( 'Custom', 'neve' ), 'icon' => 'text', ], ], 'footer_description' => [ 'inherit' => [ 'template' => esc_html__( 'Customize the default vertical spacing <ctaButton>here</ctaButton>.', 'neve' ), 'control_to_focus' => Config::MODS_CONTENT_VSPACING, ], ], ], '\Neve\Customizer\Controls\React\Radio_Buttons' ) ); $default_value = get_theme_mod( Config::MODS_CONTENT_VSPACING, $this->content_vspacing_default() ); $this->add_control( new Control( 'neve_' . $this->post_type . '_content_vspacing', [ 'default' => $default_value, 'transport' => $this->selective_refresh, ], [ 'label' => __( 'Custom Value', 'neve' ), 'sanitize_callback' => [ $this, 'sanitize_spacing_array' ], 'section' => $this->section, 'input_attrs' => [ 'units' => [ 'px', 'vh' ], 'axis' => 'vertical', 'dependsOn' => [ 'neve_' . $this->post_type . '_inherit_vspacing' => 'specific' ], ], 'default' => $default_value, 'priority' => 100, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--c-vspace', 'selector' => 'body.' . $this->post_type . ' .neve-main', 'responsive' => true, 'fallback' => '', ], 'directional' => true, ], ], '\Neve\Customizer\Controls\React\Spacing' ) ); } /** * Fuction used for active_callback control property. * * @return bool */ abstract public static function is_cover_layout(); } main.php 0000666 00000006660 15226760542 0006226 0 ustar 00 <?php /** * Handles main customzier setup like root panels. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 20/08/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Core\Settings\Mods; use Neve\Customizer\Controls\React\Documentation_Section; use Neve\Customizer\Controls\React\Instructions_Section; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Controls\Simple_Upsell; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Panel; use Neve\Customizer\Types\Section; /** * Main customizer handler. */ class Main extends Base_Customizer { /** * Add controls. */ public function add_controls() { $this->register_types(); $this->add_main_panels(); $this->change_controls(); } /** * Register customizer controls type. */ private function register_types() { $this->register_type( 'Neve\Customizer\Controls\Radio_Image', 'control' ); $this->register_type( 'Neve\Customizer\Controls\Range', 'control' ); $this->register_type( 'Neve\Customizer\Controls\Responsive_Number', 'control' ); $this->register_type( 'Neve\Customizer\Controls\Tabs', 'control' ); $this->register_type( 'Neve\Customizer\Controls\Heading', 'control' ); $this->register_type( 'Neve\Customizer\Controls\Checkbox', 'control' ); $this->register_type( 'Neve\Customizer\Controls\Upsell_Control', 'control' ); } /** * Add main panels. */ private function add_main_panels() { $panels = array( 'neve_layout' => array( 'priority' => 25, 'title' => __( 'Layout', 'neve' ), ), 'neve_typography' => array( 'priority' => 35, 'title' => __( 'Typography', 'neve' ), ), ); foreach ( $panels as $panel_id => $panel ) { $this->add_panel( new Panel( $panel_id, array( 'priority' => $panel['priority'], 'title' => $panel['title'], ) ) ); } $this->wpc->add_section( new Instructions_Section( $this->wpc, 'neve_typography_quick_links', array( 'priority' => - 100, 'panel' => 'neve_typography', 'type' => 'hfg_instructions', 'options' => array( 'quickLinks' => array( 'neve_body_font_family' => array( 'label' => esc_html__( 'Change main font', 'neve' ), 'icon' => 'dashicons-editor-spellcheck', ), 'neve_headings_font_family' => array( 'label' => esc_html__( 'Change headings font', 'neve' ), 'icon' => 'dashicons-heading', ), 'neve_h1_accordion_wrap' => array( 'label' => esc_html__( 'Change H1 font size', 'neve' ), 'icon' => 'dashicons-info-outline', ), 'neve_archive_typography_post_title' => array( 'label' => esc_html__( 'Change archive font size', 'neve' ), 'icon' => 'dashicons-sticky', ), ), ), ) ) ); $this->wpc->add_section( new Documentation_Section( $this->wpc, 'neve_documentation', [ 'priority' => PHP_INT_MAX, 'title' => esc_html__( 'Neve', 'neve' ), 'url' => tsdk_utmify( 'https://docs.themeisle.com/article/946-neve-doc', 'docsbtn' ), ] ) ); } /** * Change controls */ protected function change_controls() { $this->change_customizer_object( 'section', 'static_front_page', 'panel', 'neve_layout' ); // Change default for shop columns WooCommerce option. $this->change_customizer_object( 'setting', 'woocommerce_catalog_columns', 'default', 3 ); } } typography.php 0000666 00000040742 15226760542 0007507 0 ustar 00 <?php /** * Customizer typography controls. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 20/08/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Core\Settings\Config; use Neve\Core\Settings\Mods; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Controls\React\Typography_Extra_Section; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Section; use Neve\Core\Traits\Theme_Mods; /** * Class Typography * * @package Neve\Customizer\Options */ class Typography extends Base_Customizer { use Theme_Mods; const HEADINGS_FONT_FAMILY_SELECTORS = 'h1:not(.site-title), .single h1.entry-title, h2, h3, .woocommerce-checkout h3, h4, h5, h6'; /** * Add controls */ public function add_controls() { $this->sections_typography(); $this->controls_font_pairs(); $this->controls_typography_general(); $this->controls_typography_headings(); $this->controls_typography_blog(); $this->section_extra(); } /** * Add controls for font pair section * * @return void */ private function controls_font_pairs() { /** * Filters the font pairs that are available inside Customizer. * * @param array $pairs The font pairs array. * * @since 3.5.0 */ $pairs = apply_filters( 'neve_font_pairings', Mods::get( Config::MODS_TPOGRAPHY_FONT_PAIRS, Config::$typography_default_pairs ) ); /** * Font Pairs Control */ $this->add_control( new Control( Config::MODS_TPOGRAPHY_FONT_PAIRS, [ 'transport' => $this->selective_refresh, 'sanitize_callback' => 'sanitize_text_field', 'default' => $pairs, ], array( 'input_attrs' => array( 'pairs' => $pairs, 'description' => array( 'text' => __( 'Choose Font family presets for your Headings and Text.', 'neve' ), 'link' => apply_filters( 'neve_external_link', 'https://docs.themeisle.com/article/1340-neve-typography', esc_html__( 'Learn more', 'neve' ) ), ), ), 'label' => esc_html__( 'Font presets', 'neve' ), 'section' => 'typography_font_pair_section', 'priority' => 10, 'type' => 'neve_font_pairings_control', ), '\Neve\Customizer\Controls\React\Font_Pairings' ) ); } /** * Add the customizer section. */ private function sections_typography() { $typography_sections = array( 'typography_font_pair_section' => array( 'title' => __( 'Font presets', 'neve' ), 'priority' => 15, ), 'neve_typography_general' => array( 'title' => __( 'General', 'neve' ), 'priority' => 25, ), 'neve_typography_headings' => array( 'title' => __( 'Headings', 'neve' ), 'priority' => 35, ), 'neve_typography_blog' => array( 'title' => __( 'Blog', 'neve' ), 'priority' => 45, ), ); foreach ( $typography_sections as $section_id => $section_data ) { $this->add_section( new Section( $section_id, array( 'title' => $section_data['title'], 'panel' => 'neve_typography', 'priority' => $section_data['priority'], ) ) ); } } /** * Add general typography controls */ private function controls_typography_general() { /** * Body font family */ $this->add_control( new Control( Config::MODS_FONT_GENERAL, [ 'transport' => $this->selective_refresh, 'sanitize_callback' => 'sanitize_text_field', 'default' => Mods::get_alternative_mod_default( Config::MODS_FONT_GENERAL ), ], array( 'settings' => [ 'default' => Config::MODS_FONT_GENERAL, 'variants' => Config::MODS_FONT_GENERAL_VARIANTS, ], 'label' => esc_html__( 'Body', 'neve' ), 'section' => 'neve_typography_general', 'priority' => 10, 'type' => 'neve_font_family_control', 'live_refresh_selector' => apply_filters( 'neve_body_font_family_selectors', 'body, .site-title' ), 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--bodyfontfamily', 'selector' => 'body', 'fallback' => Mods::get_alternative_mod_default( Config::MODS_FONT_GENERAL ), 'suffix' => ', var(--nv-fallback-ff)', ], ], ), '\Neve\Customizer\Controls\React\Font_Family' ) ); /** * Body font family subsets. */ $this->wpc->add_setting( Config::MODS_FONT_GENERAL_VARIANTS, [ 'transport' => $this->selective_refresh, 'sanitize_callback' => 'neve_sanitize_font_variants', 'default' => [], ] ); $defaults = Mods::get_alternative_mod_default( Config::MODS_TYPEFACE_GENERAL ); $this->add_control( new Control( Config::MODS_TYPEFACE_GENERAL, [ 'transport' => $this->selective_refresh, 'default' => $defaults, ], [ 'priority' => 11, 'section' => 'neve_typography_general', 'input_attrs' => array( 'size_units' => [ 'px', 'em', 'rem' ], 'weight_default' => 400, 'size_default' => $defaults['fontSize'], 'line_height_default' => $defaults['lineHeight'], 'letter_spacing_default' => $defaults['letterSpacing'], ), 'type' => 'neve_typeface_control', 'font_family_control' => 'neve_body_font_family', 'live_refresh_selector' => 'body, .site-title', 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => [ '--bodytexttransform' => 'textTransform', '--bodyfontweight' => 'fontWeight', '--bodyfontsize' => [ 'key' => 'fontSize', 'responsive' => true, ], '--bodylineheight' => [ 'key' => 'lineHeight', 'responsive' => true, ], '--bodyletterspacing' => [ 'key' => 'letterSpacing', 'suffix' => 'px', 'responsive' => true, ], ], 'selector' => 'body', ], ], ], '\Neve\Customizer\Controls\React\Typography' ) ); /** * Fallback Font Family. */ $this->add_control( new Control( 'neve_fallback_font_family', [ 'transport' => $this->selective_refresh, 'sanitize_callback' => 'sanitize_text_field', 'default' => 'Arial, Helvetica, sans-serif', ], [ 'label' => esc_html__( 'Fallback Font', 'neve' ), 'section' => 'neve_typography_general', 'priority' => 12, 'type' => 'neve_font_family_control', 'input_attrs' => [ 'system' => true, 'link' => [ 'string' => __( 'Learn more about fallback fonts', 'neve' ), 'url' => esc_url( 'https://docs.themeisle.com/article/1319-fallback-fonts' ), 'new_tab' => true, ], ], 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--nv-fallback-ff', 'selector' => 'body', ], ], ], '\Neve\Customizer\Controls\React\Font_Family' ) ); } /** * Add controls for typography headings. */ private function controls_typography_headings() { /** * Headings font family */ $this->add_control( new Control( 'neve_headings_font_family', array( 'transport' => $this->selective_refresh, 'sanitize_callback' => 'sanitize_text_field', ), array( 'section' => 'neve_typography_headings', 'priority' => 10, 'type' => 'neve_font_family_control', 'live_refresh_selector' => apply_filters( 'neve_headings_font_family_selectors', self::HEADINGS_FONT_FAMILY_SELECTORS ), 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--headingsfontfamily', 'selector' => 'body', 'fallback' => 'var(--bodyfontfamily, var(--nv-fallback-ff))', ], 'type' => 'svg-icon-size', ], 'input_attrs' => [ 'default_is_inherit' => true, ], ), '\Neve\Customizer\Controls\React\Font_Family' ) ); $selectors = neve_get_headings_selectors(); $priority = 20; foreach ( [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ] as $heading_id ) { $this->add_control( new Control( 'neve_' . $heading_id . '_accordion_wrap', array( 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ), array( 'label' => $heading_id, 'section' => 'neve_typography_headings', 'priority' => $priority += 1, 'class' => esc_attr( 'advanced-sidebar-accordion-' . $heading_id ), 'accordion' => true, 'controls_to_wrap' => 2, 'expanded' => false, ), 'Neve\Customizer\Controls\React\Heading' ) ); $mod_key_font_family = $this->get_mod_key_heading_fontfamily( $heading_id ); /** * Headings font family */ $this->add_control( new Control( $mod_key_font_family, array( 'transport' => $this->selective_refresh, 'sanitize_callback' => 'sanitize_text_field', ), array( 'section' => 'neve_typography_headings', 'priority' => $priority += 1, 'type' => 'neve_font_family_control', 'live_refresh_selector' => apply_filters( $mod_key_font_family . '_selectors', self::HEADINGS_FONT_FAMILY_SELECTORS ), 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--' . $heading_id . 'fontfamily', 'selector' => 'body', 'fallback' => 'var(--headingsfontfamily, var(--bodyfontfamily))', ], 'type' => 'svg-icon-size', ], 'input_attrs' => [ 'default_is_inherit' => true, ], ), '\Neve\Customizer\Controls\React\Font_Family' ) ); $mod_key = 'neve_' . $heading_id . '_typeface_general'; $default_values = Mods::get_alternative_mod_default( $mod_key ); $this->add_control( new Control( $mod_key, [ 'transport' => $this->selective_refresh, 'default' => $default_values, ], [ 'priority' => $priority += 2, 'section' => 'neve_typography_headings', 'input_attrs' => array( 'size_units' => [ 'em', 'px', 'rem' ], 'weight_default' => $default_values['fontWeight'], 'size_default' => $default_values['fontSize'], 'line_height_default' => $default_values['lineHeight'], 'letter_spacing_default' => $default_values['letterSpacing'], ), 'type' => 'neve_typeface_control', 'font_family_control' => $mod_key_font_family, 'live_refresh_selector' => $selectors[ $heading_id ], 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => [ '--' . $heading_id . 'texttransform' => 'textTransform', '--' . $heading_id . 'fontweight' => 'fontWeight', '--' . $heading_id . 'fontsize' => [ 'key' => 'fontSize', 'responsive' => true, ], '--' . $heading_id . 'lineheight' => [ 'key' => 'lineHeight', 'responsive' => true, ], '--' . $heading_id . 'letterspacing' => [ 'key' => 'letterSpacing', 'suffix' => 'px', 'responsive' => true, ], ], 'selector' => 'body', ], ], ], '\Neve\Customizer\Controls\React\Typography' ) ); } } /** * Add controls for blog typography. */ private function controls_typography_blog() { $controls = array( 'neve_archive_typography_post_title' => array( 'label' => __( 'Post title', 'neve' ), 'category_label' => __( 'Blog Archive', 'neve' ), 'priority' => 10, 'font_family_control' => 'neve_headings_font_family', 'live_refresh_selector' => '.blog .blog-entry-title, .archive .blog-entry-title', ), 'neve_archive_typography_post_excerpt' => array( 'label' => __( 'Post excerpt', 'neve' ), 'priority' => 20, 'font_family_control' => 'neve_body_font_family', 'live_refresh_selector' => '.blog .entry-summary, .archive .entry-summary, .blog .post-pages-links', ), 'neve_archive_typography_post_meta' => array( 'label' => __( 'Post meta', 'neve' ), 'priority' => 30, 'font_family_control' => 'neve_body_font_family', 'live_refresh_selector' => '.blog .nv-meta-list li, .archive .nv-meta-list li', ), 'neve_single_post_typography_post_title' => array( 'label' => __( 'Post title', 'neve' ), 'category_label' => __( 'Single Post', 'neve' ), 'priority' => 40, 'font_family_control' => 'neve_headings_font_family', 'live_refresh_selector' => '.single h1.entry-title', ), 'neve_single_post_typography_post_meta' => array( 'label' => __( 'Post meta', 'neve' ), 'priority' => 50, 'font_family_control' => 'neve_body_font_family', 'live_refresh_selector' => '.single .nv-meta-list li', ), 'neve_single_post_typography_comments_title' => array( 'label' => __( 'Comments reply title', 'neve' ), 'priority' => 60, 'font_family_control' => 'neve_headings_font_family', 'live_refresh_selector' => '.single .comment-reply-title', ), ); foreach ( $controls as $control_id => $control_settings ) { $settings = array( 'label' => $control_settings['label'], 'section' => 'neve_typography_blog', 'priority' => $control_settings['priority'], 'class' => esc_attr( 'typography-blog-' . $control_id ), 'accordion' => true, 'controls_to_wrap' => 1, 'expanded' => false, ); if ( array_key_exists( 'category_label', $control_settings ) ) { $settings['category_label'] = $control_settings['category_label']; } $this->add_control( new Control( $control_id . '_accordion_wrap', array( 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ), $settings, 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( $control_id, [ 'transport' => $this->selective_refresh, ], [ 'priority' => $control_settings['priority'] += 1, 'section' => 'neve_typography_blog', 'type' => 'neve_typeface_control', 'font_family_control' => $control_settings['font_family_control'], 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => [ '--texttransform' => 'textTransform', '--fontweight' => 'fontWeight', '--fontsize' => [ 'key' => 'fontSize', 'responsive' => true, ], '--lineheight' => [ 'key' => 'lineHeight', 'responsive' => true, ], '--letterspacing' => [ 'key' => 'letterSpacing', 'suffix' => 'px', 'responsive' => true, ], ], 'selector' => $control_settings['live_refresh_selector'], ], ], 'refresh_on_reset' => true, 'input_attrs' => array( 'default_is_empty' => true, 'size_units' => [ 'em', 'px', 'rem' ], 'weight_default' => 'none', 'size_default' => array( 'suffix' => array( 'mobile' => 'px', 'tablet' => 'px', 'desktop' => 'px', ), 'mobile' => '', 'tablet' => '', 'desktop' => '', ), 'line_height_default' => array( 'mobile' => '', 'tablet' => '', 'desktop' => '', ), 'letter_spacing_default' => array( 'mobile' => '', 'tablet' => '', 'desktop' => '', ), ), ], '\Neve\Customizer\Controls\React\Typography' ) ); } } /** * Add section for extra inline controls * * @return void */ private function section_extra() { $this->wpc->add_section( new Typography_Extra_Section( $this->wpc, 'typography_extra_section', [ 'priority' => 9999, // upsell priority(10000) - 1 'panel' => 'neve_typography', ] ) ); } } layout_blog.php 0000666 00000076352 15226760542 0007627 0 ustar 00 <?php /** * Blog layout section. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 20/08/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Defaults\Layout; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Section; /** * Class Layout_Blog * * @package Neve\Customizer\Options */ class Layout_Blog extends Base_Customizer { use Layout; /** * Holds the section name. * * @var string $section */ private $section = 'neve_blog_archive_layout'; /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { $this->section_blog(); $this->add_layout_controls(); $this->add_featured_post(); $this->add_content_ordering_controls(); $this->add_post_meta_controls(); $this->add_typography_shortcut(); add_action( 'customize_register', [ $this, 'adapt_old_pro' ], PHP_INT_MAX ); } /** * Adapting old pro versions to make them still usable with the old theme version. */ public function adapt_old_pro() { if ( ! defined( 'NEVE_PRO_VERSION' ) ) { return; } if ( version_compare( NEVE_PRO_VERSION, '1.2.8', '>' ) ) { return; } $changes = [ 'neve_posts_order' => [ 'priority' => 51 ], 'neve_post_content_ordering' => [ 'active_callback' => '__return_true' ], 'neve_blog_ordering_content_heading' => [ 'controls_to_wrap' => 6 ], 'neve_blog_post_meta_heading' => [ 'controls_to_wrap' => 3 ], 'neve_read_more_options' => [ 'accordion' => true, 'expanded' => false, 'class' => 'read-more-options-accordion', ], ]; foreach ( $changes as $control_slug => $props ) { foreach ( $props as $prop => $new_value ) { $this->change_customizer_object( 'control', $control_slug, $prop, $new_value ); } } $this->wpc->remove_control( 'neve_metadata_options' ); } /** * Add customize section */ private function section_blog() { $this->add_section( new Section( $this->section, array( 'priority' => 35, 'title' => esc_html__( 'Blog / Archive', 'neve' ), 'panel' => 'neve_layout', ) ) ); } /** * Add blog layout controls. */ private function add_layout_controls() { $this->add_control( new Control( 'neve_blog_layout_heading', array( 'sanitize_callback' => 'sanitize_text_field', ), array( 'label' => esc_html__( 'Blog Layout', 'neve' ), 'section' => $this->section, 'priority' => 10, 'class' => 'blog-layout-accordion', 'accordion' => true, 'controls_to_wrap' => 6, ), 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( $this->section, [ 'default' => 'grid', 'sanitize_callback' => [ $this, 'sanitize_blog_layout' ], ], [ 'section' => $this->section, 'priority' => 11, 'choices' => [ 'default' => [ 'name' => __( 'List', 'neve' ), 'image' => 'data:image/png;base64,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', ], 'covers' => [ 'name' => __( 'Covers', 'neve' ), 'image' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF4AAAB5CAYAAACwe5bgAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMvSURBVHgB7d1PTxNBGMfxp1JTLH8ExXAg8eDNd+Xr9eaNg8FEQxSpgIVSKBTccdMEaElnO535PYfvJ9lLQ8j0y3ZKuzu7rfuKobgXBgnCixBehPAihBchvAjhRQgvQngRwosQXqQd80PXt2a9gbmws27WWXn82O2d2dG5ubDdNeu+nP9z0eEP++bC5up0+PGdn/F12nHhmWpECC9CeBHCixBehPAihBchvAjhRQgvQngRwosQXoTwIoQXIbwI4UWijkA9tLNWbV3LZv/Ykmx0zPY2LZtvp/URuVSNw4fDbuHwm1fexzfROPxxddD7/Nrc6ldj2/9t2Sxjbw8ahx+N680r7+ObaBx++1W9LSr3KybM8e/WbGGnw3rLrXH4cOrCTsIT619V4S2fMMenjC9MJS7DnwzT5rl+5veH8PsP/tjCBjdWROPww5t68yrM771Lc48PUCKt2HWuy/o3KtVKNYe3W9OPex/fUy0WGGsw1YgQXoTwItHnx3v5fmarO/3mFRYmnBX40BMjfHLuRFSNDn9wYi58bNdP7qGwMMHL+D68iQvPVCNCeBHCixBehPAihBchvAjhRQgvQngRwosQXoTwIoQXIbwI4UUIL0J4kcan8LWrP9VKxj9X6olJ3sc30Tj87rrZ3mvL5vMPS7K1Wh33fGvZfPkpWooTjuh7OV1ulvG97/FNNA5/dFFvXpVaWJCKN1eRxnt8WMqYMseHRQM5z18PS0FT5vjDv2UuHsoeL9J4jw97g5fLyc4SXk2sCMGzovb48IHk6fmKKs99OPIyvk7kHMKKEBGmGhHCixBehPAiUe/BlyOz72fmwvvt6VtBhC/uvvbMhd2NuItsRIUPT6zvZA1UWHYz6zEv44u9gAVTjQjhRQgvQngRwosQXoTwIoQXIbwI4UUIL0J4EcKLEF6E8CKEFyG8SPGTVudJXZiQetLqPMtamMAeL8JJqyLs8SLF7wP16yLvVVFT7wP1/xUzsOyK3wcq95NKHV+pS/kWvw/UYGRZpd4H6qrQikHuAyXCm6sICxNE2ONFCC9CeBHCixBehPAihBchvAjhRQgvQniR8O3kJ0Nx/wAXONq4kNEpFQAAAABJRU5ErkJggg==', ], 'grid' => [ 'name' => __( 'Grid', 'neve' ), 'image' => 'data:image/jpeg;base64,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', ], ], ], '\Neve\Customizer\Controls\React\Radio_Image' ) ); $grid_layout_default = '{"desktop":3,"tablet":2,"mobile":1}'; $this->add_control( new Control( 'neve_grid_layout', array( 'sanitize_callback' => 'neve_sanitize_range_value', 'default' => $grid_layout_default, ), array( 'label' => esc_html__( 'Columns', 'neve' ), 'section' => $this->section, 'units' => array( 'items', ), 'input_attrs' => [ 'min' => 1, 'max' => 4, 'defaultVal' => json_decode( $grid_layout_default, true ), ], 'priority' => 11, 'active_callback' => array( $this, 'is_column_layout' ), ), 'Neve\Customizer\Controls\React\Responsive_Range' ) ); $this->add_control( new Control( 'neve_blog_covers_text_color', array( 'sanitize_callback' => 'neve_sanitize_colors', 'default' => '#ffffff', 'transport' => 'postMessage', ), array( 'label' => esc_html__( 'Text Color', 'neve' ), 'section' => $this->section, 'priority' => 15, 'default' => '#ffffff', 'active_callback' => function () { return get_theme_mod( $this->section ) === 'covers'; }, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--color', 'selector' => '.neve-main', ], ], ), 'Neve\Customizer\Controls\React\Color' ) ); $this->add_control( new Control( 'neve_archive_hide_title', [ 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => false, ], [ 'label' => esc_html__( 'Disable Title', 'neve' ), 'section' => $this->section, 'type' => 'neve_toggle_control', 'priority' => 16, 'active_callback' => function() { return get_option( 'show_on_front' ) !== 'posts'; }, ], 'Neve\Customizer\Controls\Checkbox' ) ); $this->add_control( new Control( 'neve_blog_list_alternative_layout', array( 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => false, ), array( 'type' => 'neve_toggle_control', 'priority' => 17, 'section' => $this->section, 'label' => esc_html__( 'Alternating layout', 'neve' ), 'active_callback' => function () { $is_list_layout = get_theme_mod( $this->section ) === 'default'; $has_image = true; if ( $is_list_layout && defined( 'NEVE_PRO_VERSION' ) ) { $has_image = get_theme_mod( 'neve_blog_list_image_position', 'left' ) !== 'no'; } return $is_list_layout && $has_image; }, ) ) ); $this->add_control( new Control( 'neve_enable_masonry', array( 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => false, ), array( 'type' => 'neve_toggle_control', 'priority' => 35, 'section' => $this->section, 'label' => esc_html__( 'Enable Masonry', 'neve' ), 'active_callback' => array( $this, 'should_show_masonry' ), ) ) ); } /** * Add featured post controls. */ private function add_featured_post() { $this->add_control( new Control( 'neve_featured_post_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'Featured Post', 'neve' ), 'section' => $this->section, 'priority' => 40, 'class' => 'featured-post-accordion', 'accordion' => true, 'expanded' => false, 'controls_to_wrap' => 2, ], 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_enable_featured_post', [ 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => false, ], [ 'label' => esc_html__( 'Enable featured post section', 'neve' ), 'section' => $this->section, 'type' => 'neve_toggle_control', 'priority' => 41, ], 'Neve\Customizer\Controls\Checkbox' ) ); $this->add_control( new Control( 'neve_featured_post_target', array( 'default' => 'latest', 'sanitize_callback' => array( $this, 'sanitize_featured_post_target' ), ), array( 'label' => esc_html__( 'Featured Post', 'neve' ), 'section' => $this->section, 'priority' => 42, 'type' => 'select', 'choices' => [ 'latest' => esc_html__( 'Latest Post', 'neve' ), 'sticky' => esc_html__( 'Sticky Post', 'neve' ), ], 'active_callback' => function() { return get_theme_mod( 'neve_enable_featured_post', false ); }, ) ) ); } /** * Add content ordering and controls. */ private function add_content_ordering_controls() { $this->add_control( new Control( 'neve_blog_ordering_content_heading', array( 'sanitize_callback' => 'sanitize_text_field', ), array( 'label' => esc_html__( 'Ordering and Content', 'neve' ), 'section' => $this->section, 'priority' => 50, 'class' => 'blog-layout-ordering-content-accordion', 'accordion' => true, 'expanded' => false, 'controls_to_wrap' => 4, ), 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_pagination_type', array( 'default' => 'number', 'sanitize_callback' => array( $this, 'sanitize_pagination_type' ), ), array( 'label' => esc_html__( 'Post Pagination', 'neve' ), 'section' => $this->section, 'priority' => 53, 'type' => 'select', 'choices' => array( 'number' => esc_html__( 'Number', 'neve' ), 'infinite' => esc_html__( 'Infinite Scroll', 'neve' ), 'jump-to' => esc_html__( 'Number', 'neve' ) . ' & ' . esc_html__( 'Search Field', 'neve' ), ), ) ) ); $order_default_components = array( 'thumbnail', 'title-meta', 'excerpt', ); $components = array( 'thumbnail' => __( 'Thumbnail', 'neve' ), 'title-meta' => __( 'Title & Meta', 'neve' ), 'excerpt' => __( 'Excerpt', 'neve' ), ); $this->add_control( new Control( 'neve_post_content_ordering', array( 'sanitize_callback' => array( $this, 'sanitize_post_content_ordering' ), 'default' => wp_json_encode( $order_default_components ), ), array( 'label' => esc_html__( 'Post Content Order', 'neve' ), 'section' => $this->section, 'components' => $components, 'priority' => 55, ), 'Neve\Customizer\Controls\React\Ordering' ) ); $this->add_control( new Control( 'neve_post_excerpt_length', array( 'sanitize_callback' => 'neve_sanitize_range_value', 'default' => 25, ), array( 'label' => esc_html__( 'Excerpt Length', 'neve' ), 'section' => $this->section, 'type' => 'neve_range_control', 'input_attrs' => [ 'min' => 5, 'max' => 300, 'defaultVal' => 25, 'step' => 5, ], 'priority' => 58, ), 'Neve\Customizer\Controls\React\Range' ) ); $this->add_control( new Control( 'neve_post_thumbnail_box_shadow', array( 'sanitize_callback' => 'absint', 'default' => 0, ), array( 'label' => esc_html__( 'Thumbnail Shadow', 'neve' ), 'section' => $this->section, 'type' => 'neve_range_control', 'step' => 1, 'input_attrs' => [ 'min' => 0, 'max' => 5, 'defaultVal' => 0, ], 'priority' => 59, ), 'Neve\Customizer\Controls\React\Range' ) ); } /** * Add controls for post meta. */ private function add_post_meta_controls() { $this->add_control( new Control( 'neve_blog_post_meta_heading', array( 'sanitize_callback' => 'sanitize_text_field', ), array( 'label' => esc_html__( 'Post Meta', 'neve' ), 'section' => $this->section, 'priority' => 70, 'class' => 'blog-layout-post-meta-accordion', 'accordion' => true, 'controls_to_wrap' => 5, 'expanded' => false, ), 'Neve\Customizer\Controls\Heading' ) ); $default = wp_json_encode( [ 'author', 'date', 'comments' ] ); $default_value = neve_get_default_meta_value( 'neve_post_meta_ordering', $default ); $this->add_control( new Control( 'neve_blog_post_meta_fields', [ 'sanitize_callback' => 'neve_sanitize_meta_repeater', 'default' => wp_json_encode( $default_value ), ], [ 'label' => esc_html__( 'Meta Order', 'neve' ), 'section' => $this->section, 'fields' => [ 'hide_on_mobile' => [ 'type' => 'checkbox', 'label' => __( 'Hide on mobile', 'neve' ), ], ], 'components' => apply_filters( 'neve_meta_filter', array( 'author' => __( 'Author', 'neve' ), 'category' => __( 'Category', 'neve' ), 'date' => __( 'Date', 'neve' ), 'comments' => __( 'Comments', 'neve' ), ) ), 'allow_new_fields' => 'no', 'priority' => 71, 'active_callback' => [ $this, 'should_show_meta_order' ], ], '\Neve\Customizer\Controls\React\Repeater' ) ); $this->add_control( new Control( 'neve_metadata_separator', array( 'sanitize_callback' => 'sanitize_text_field', 'default' => esc_html( '/' ), ), array( 'priority' => 72, 'section' => $this->section, 'label' => esc_html__( 'Separator', 'neve' ), 'description' => esc_html__( 'For special characters make sure to use Unicode. For example > can be displayed using \003E.', 'neve' ), 'type' => 'text', ) ) ); $this->add_control( new Control( 'neve_author_avatar', array( 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => false, ), array( 'label' => esc_html__( 'Show Author Avatar', 'neve' ), 'section' => $this->section, 'type' => 'neve_toggle_control', 'priority' => 73, ) ) ); $this->add_control( new Control( 'neve_author_avatar_size', array( 'sanitize_callback' => 'neve_sanitize_range_value', 'default' => '{ "mobile": 20, "tablet": 20, "desktop": 20 }', ), array( 'label' => esc_html__( 'Avatar Size', 'neve' ), 'section' => $this->section, 'units' => array( 'px', ), 'input_attr' => array( 'mobile' => array( 'min' => 20, 'max' => 50, 'default' => 20, 'default_unit' => 'px', ), 'tablet' => array( 'min' => 20, 'max' => 50, 'default' => 20, 'default_unit' => 'px', ), 'desktop' => array( 'min' => 20, 'max' => 50, 'default' => 20, 'default_unit' => 'px', ), ), 'input_attrs' => [ 'min' => self::RELATIVE_CSS_UNIT_SUPPORTED_MIN_VALUE, 'max' => 50, 'defaultVal' => [ 'mobile' => 20, 'tablet' => 20, 'desktop' => 20, 'suffix' => [ 'mobile' => 'px', 'tablet' => 'px', 'desktop' => 'px', ], ], 'units' => [ 'px', 'em', 'rem' ], ], 'priority' => 74, 'active_callback' => function () { return get_theme_mod( 'neve_author_avatar', false ); }, 'responsive' => true, ), 'Neve\Customizer\Controls\React\Responsive_Range' ) ); $this->add_control( new Control( 'neve_show_last_updated_date', array( 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => false, ), array( 'label' => esc_html__( 'Use last updated date instead of the published one', 'neve' ), 'section' => $this->section, 'type' => 'neve_toggle_control', 'priority' => 85, ) ) ); } /** * Sanitize the container layout value * * @param string $value value from the control. * * @return string */ public function sanitize_blog_layout( $value ) { $allowed_values = array( 'default', 'covers', 'grid' ); if ( ! in_array( $value, $allowed_values, true ) ) { return 'grid'; } return sanitize_text_field( $value ); } /** * Sanitize the pagination type * * @param string $value value from the control. * * @return string */ public function sanitize_pagination_type( $value ) { $allowed_values = array( 'number', 'infinite', 'jump-to' ); if ( ! in_array( $value, $allowed_values, true ) ) { return 'number'; } return esc_html( $value ); } /** * Sanitize featured post target * * @param string $value value from the control. * * @return string */ public function sanitize_featured_post_target( $value ) { $allowed_values = [ 'sticky', 'latest' ]; if ( ! in_array( $value, $allowed_values, true ) ) { return 'latest'; } return esc_html( $value ); } /** * Sanitize content order control. */ public function sanitize_post_content_ordering( $value ) { $allowed = array( 'thumbnail', 'title-meta', 'excerpt', ); if ( empty( $value ) ) { return wp_json_encode( $allowed ); } $decoded = json_decode( $value, true ); foreach ( $decoded as $val ) { if ( ! in_array( $val, $allowed, true ) ) { return wp_json_encode( $allowed ); } } return $value; } /** * Callback to show the meta order control. * * @return bool */ public function should_show_meta_order() { $default = array( 'thumbnail', 'title-meta', 'excerpt', ); $content_order = get_theme_mod( 'neve_post_content_ordering', wp_json_encode( $default ) ); $content_order = json_decode( $content_order, true ); if ( ! in_array( 'title-meta', $content_order, true ) ) { return false; } return true; } /** * Callback to show grid columns control. * * @return bool */ public function is_column_layout() { $blog_layout = get_theme_mod( $this->section, 'grid' ); return in_array( $blog_layout, [ 'grid', 'covers' ], true ); } /** * Callback to show masonry control. * * @return bool */ public function should_show_masonry() { if ( ! $this->is_column_layout() ) { return false; } $columns = json_decode( get_theme_mod( 'neve_grid_layout', $this->grid_columns_default() ), true ); $columns = array_filter( array_values( $columns ), function ( $value ) { return $value > 1; } ); if ( empty( $columns ) ) { return false; } return true; } /** * Add typography shortcut. */ private function add_typography_shortcut() { $this->add_control( new Control( 'neve_blog_typography_shortcut', array( 'sanitize_callback' => 'neve_sanitize_text_field', ), array( 'button_class' => 'nv-top-bar-menu-shortcut', 'text_before' => __( 'Customize Typography for the Archive page', 'neve' ), 'text_after' => '.', 'button_text' => __( 'here', 'neve' ), 'is_button' => false, 'control_to_focus' => 'neve_archive_typography_post_title_accordion_wrap', 'shortcut' => true, 'section' => $this->section, 'priority' => 1000, ), '\Neve\Customizer\Controls\Button' ) ); } } js/elFinderVolumeLocalFileSystem.class.php 0000666 00000136366 15226760542 0014731 0 ustar 00 <?php // Implement similar functionality in PHP 5.2 or 5.3 // http://php.net/manual/class.recursivecallbackfilteriterator.php#110974 if (!class_exists('RecursiveCallbackFilterIterator', false)) { class RecursiveCallbackFilterIterator extends RecursiveFilterIterator { private $callback; public function __construct(RecursiveIterator $iterator, $callback) { $this->callback = $callback; parent::__construct($iterator); } public function accept() { return call_user_func($this->callback, parent::current(), parent::key(), parent::getInnerIterator()); } public function getChildren() { return new self($this->getInnerIterator()->getChildren(), $this->callback); } } } /** * elFinder driver for local filesystem. * * @author Dmitry (dio) Levashov * @author Troex Nevelin **/ class elFinderVolumeLocalFileSystem extends elFinderVolumeDriver { /** * Driver id * Must be started from letter and contains [a-z0-9] * Used as part of volume id * * @var string **/ protected $driverId = 'l'; /** * Required to count total archive files size * * @var int **/ protected $archiveSize = 0; /** * Is checking stat owner * * @var boolean */ protected $statOwner = false; /** * Path to quarantine directory * * @var string */ private $quarantine; /** * Constructor * Extend options with required fields * * @author Dmitry (dio) Levashov */ public function __construct() { $this->options['alias'] = ''; // alias to replace root dir name $this->options['dirMode'] = 0755; // new dirs mode $this->options['fileMode'] = 0644; // new files mode $this->options['rootCssClass'] = 'elfinder-navbar-root-local'; $this->options['followSymLinks'] = true; $this->options['detectDirIcon'] = ''; // file name that is detected as a folder icon e.g. '.diricon.png' $this->options['keepTimestamp'] = array('copy', 'move'); // keep timestamp at inner filesystem allowed 'copy', 'move' and 'upload' $this->options['substituteImg'] = true; // support substitute image with dim command $this->options['statCorrector'] = null; // callable to correct stat data `function(&$stat, $path, $statOwner, $volumeDriveInstance){}` if (DIRECTORY_SEPARATOR === '/') { // Linux $this->options['acceptedName'] = '/^[^\.\/\x00][^\/\x00]*$/'; } else { // Windows $this->options['acceptedName'] = '/^[^\.\/\x00\\\:*?"<>|][^\/\x00\\\:*?"<>|]*$/'; } } /*********************************************************************/ /* INIT AND CONFIGURE */ /*********************************************************************/ /** * Prepare driver before mount volume. * Return true if volume is ready. * * @return bool **/ protected function init() { // Normalize directory separator for windows if (DIRECTORY_SEPARATOR !== '/') { foreach (array('path', 'tmbPath', 'tmpPath', 'quarantine') as $key) { if (!empty($this->options[$key])) { $this->options[$key] = str_replace('/', DIRECTORY_SEPARATOR, $this->options[$key]); } } // PHP >= 7.1 Supports UTF-8 path on Windows if (version_compare(PHP_VERSION, '7.1', '>=')) { $this->options['encoding'] = ''; $this->options['locale'] = ''; } } if (!$cwd = getcwd()) { return $this->setError('elFinder LocalVolumeDriver requires a result of getcwd().'); } // detect systemRoot if (!isset($this->options['systemRoot'])) { if ($cwd[0] === DIRECTORY_SEPARATOR || $this->root[0] === DIRECTORY_SEPARATOR) { $this->systemRoot = DIRECTORY_SEPARATOR; } else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $this->root, $m)) { $this->systemRoot = $m[1]; } else if (preg_match('/^([a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . ')/', $cwd, $m)) { $this->systemRoot = $m[1]; } } $this->root = $this->getFullPath($this->root, $cwd); if (!empty($this->options['startPath'])) { $this->options['startPath'] = $this->getFullPath($this->options['startPath'], $this->root); } if (is_null($this->options['syncChkAsTs'])) { $this->options['syncChkAsTs'] = true; } if (is_null($this->options['syncCheckFunc'])) { $this->options['syncCheckFunc'] = array($this, 'localFileSystemInotify'); } // check 'statCorrector' if (empty($this->options['statCorrector']) || !is_callable($this->options['statCorrector'])) { $this->options['statCorrector'] = null; } return true; } /** * Configure after successfull mount. * * @return void * @throws elFinderAbortException * @author Dmitry (dio) Levashov */ protected function configure() { $hiddens = array(); $root = $this->stat($this->root); // check thumbnails path if (!empty($this->options['tmbPath'])) { if (strpos($this->options['tmbPath'], DIRECTORY_SEPARATOR) === false) { $hiddens['tmb'] = $this->options['tmbPath']; $this->options['tmbPath'] = $this->_abspath($this->options['tmbPath']); } else { $this->options['tmbPath'] = $this->_normpath($this->options['tmbPath']); } } // check temp path if (!empty($this->options['tmpPath'])) { if (strpos($this->options['tmpPath'], DIRECTORY_SEPARATOR) === false) { $hiddens['temp'] = $this->options['tmpPath']; $this->options['tmpPath'] = $this->_abspath($this->options['tmpPath']); } else { $this->options['tmpPath'] = $this->_normpath($this->options['tmpPath']); } } // check quarantine path $_quarantine = ''; if (!empty($this->options['quarantine'])) { if (strpos($this->options['quarantine'], DIRECTORY_SEPARATOR) === false) { $_quarantine = $this->_abspath($this->options['quarantine']); $this->options['quarantine'] = ''; } else { $this->options['quarantine'] = $this->_normpath($this->options['quarantine']); } } else { $_quarantine = $this->_abspath('.quarantine'); } is_dir($_quarantine) && self::localRmdirRecursive($_quarantine); parent::configure(); // check tmbPath if (!$this->tmbPath && isset($hiddens['tmb'])) { unset($hiddens['tmb']); } // if no thumbnails url - try detect it if ($root['read'] && !$this->tmbURL && $this->URL) { if (strpos($this->tmbPath, $this->root) === 0) { $this->tmbURL = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($this->tmbPath, strlen($this->root) + 1)); if (preg_match("|[^/?&=]$|", $this->tmbURL)) { $this->tmbURL .= '/'; } } } // set $this->tmp by options['tmpPath'] $this->tmp = ''; if (!empty($this->options['tmpPath'])) { if ((is_dir($this->options['tmpPath']) || mkdir($this->options['tmpPath'], $this->options['dirMode'], true)) && is_writable($this->options['tmpPath'])) { $this->tmp = $this->options['tmpPath']; } else { if (isset($hiddens['temp'])) { unset($hiddens['temp']); } } } if (!$this->tmp && ($tmp = elFinder::getStaticVar('commonTempPath'))) { $this->tmp = $tmp; } // check quarantine dir $this->quarantine = ''; if (!empty($this->options['quarantine'])) { if ((is_dir($this->options['quarantine']) || mkdir($this->options['quarantine'], $this->options['dirMode'], true)) && is_writable($this->options['quarantine'])) { $this->quarantine = $this->options['quarantine']; } else { if (isset($hiddens['quarantine'])) { unset($hiddens['quarantine']); } } } else if ($_path = elFinder::getCommonTempPath()) { $this->quarantine = $_path; } if (!$this->quarantine) { if (!$this->tmp) { $this->archivers['extract'] = array(); $this->disabled[] = 'extract'; } else { $this->quarantine = $this->tmp; } } if ($hiddens) { foreach ($hiddens as $hidden) { $this->attributes[] = array( 'pattern' => '~^' . preg_quote(DIRECTORY_SEPARATOR . $hidden, '~') . '$~', 'read' => false, 'write' => false, 'locked' => true, 'hidden' => true ); } } if (!empty($this->options['keepTimestamp'])) { $this->options['keepTimestamp'] = array_flip($this->options['keepTimestamp']); } $this->statOwner = (!empty($this->options['statOwner'])); // enable WinRemoveTailDots plugin on Windows server if (DIRECTORY_SEPARATOR !== '/') { if (!isset($this->options['plugin'])) { $this->options['plugin'] = array(); } $this->options['plugin']['WinRemoveTailDots'] = array('enable' => true); } } /** * Long pooling sync checker * This function require server command `inotifywait` * If `inotifywait` need full path, Please add `define('ELFINER_INOTIFYWAIT_PATH', '/PATH_TO/inotifywait');` into connector.php * * @param string $path * @param int $standby * @param number $compare * * @return number|bool * @throws elFinderAbortException */ public function localFileSystemInotify($path, $standby, $compare) { if (isset($this->sessionCache['localFileSystemInotify_disable'])) { return false; } $path = realpath($path); $mtime = filemtime($path); if (!$mtime) { return false; } if ($mtime != $compare) { return $mtime; } $inotifywait = defined('ELFINER_INOTIFYWAIT_PATH') ? ELFINER_INOTIFYWAIT_PATH : 'inotifywait'; $standby = max(1, intval($standby)); $cmd = $inotifywait . ' ' . escapeshellarg($path) . ' -t ' . $standby . ' -e moved_to,moved_from,move,close_write,delete,delete_self'; $this->procExec($cmd, $o, $r); if ($r === 0) { // changed clearstatcache(); if (file_exists($path)) { $mtime = filemtime($path); // error on busy? return $mtime ? $mtime : time(); } else { // target was removed return 0; } } else if ($r === 2) { // not changed (timeout) return $compare; } // error // cache to $_SESSION $this->sessionCache['localFileSystemInotify_disable'] = true; $this->session->set($this->id, $this->sessionCache); return false; } /*********************************************************************/ /* FS API */ /*********************************************************************/ /*********************** paths/urls *************************/ /** * Return parent directory path * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _dirname($path) { return dirname($path); } /** * Return file name * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _basename($path) { return basename($path); } /** * Join dir name and file name and retur full path * * @param string $dir * @param string $name * * @return string * @author Dmitry (dio) Levashov **/ protected function _joinPath($dir, $name) { $dir = rtrim($dir, DIRECTORY_SEPARATOR); $path = realpath($dir . DIRECTORY_SEPARATOR . $name); // realpath() returns FALSE if the file does not exist if ($path === false || strpos($path, $this->root) !== 0) { if (DIRECTORY_SEPARATOR !== '/') { $dir = str_replace('/', DIRECTORY_SEPARATOR, $dir); $name = str_replace('/', DIRECTORY_SEPARATOR, $name); } // Directory traversal measures if (strpos($dir, '..' . DIRECTORY_SEPARATOR) !== false || substr($dir, -2) == '..') { $dir = $this->root; } if (strpos($name, '..' . DIRECTORY_SEPARATOR) !== false) { $name = basename($name); } $path = $dir . DIRECTORY_SEPARATOR . $name; } return $path; } /** * Return normalized path, this works the same as os.path.normpath() in Python * * @param string $path path * * @return string * @author Troex Nevelin **/ protected function _normpath($path) { if (empty($path)) { return '.'; } $changeSep = (DIRECTORY_SEPARATOR !== '/'); if ($changeSep) { $drive = ''; if (preg_match('/^([a-zA-Z]:)(.*)/', $path, $m)) { $drive = $m[1]; $path = $m[2] ? $m[2] : '/'; } $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); } if (strpos($path, '/') === 0) { $initial_slashes = true; } else { $initial_slashes = false; } if (($initial_slashes) && (strpos($path, '//') === 0) && (strpos($path, '///') === false)) { $initial_slashes = 2; } $initial_slashes = (int)$initial_slashes; $comps = explode('/', $path); $new_comps = array(); foreach ($comps as $comp) { if (in_array($comp, array('', '.'))) { continue; } if (($comp != '..') || (!$initial_slashes && !$new_comps) || ($new_comps && (end($new_comps) == '..'))) { array_push($new_comps, $comp); } elseif ($new_comps) { array_pop($new_comps); } } $comps = $new_comps; $path = implode('/', $comps); if ($initial_slashes) { $path = str_repeat('/', $initial_slashes) . $path; } if ($changeSep) { $path = $drive . str_replace('/', DIRECTORY_SEPARATOR, $path); } return $path ? $path : '.'; } /** * Return file path related to root dir * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _relpath($path) { if ($path === $this->root) { return ''; } else { if (strpos($path, $this->root) === 0) { return ltrim(substr($path, strlen($this->root)), DIRECTORY_SEPARATOR); } else { // for link return $path; } } } /** * Convert path related to root dir into real path * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _abspath($path) { if ($path === DIRECTORY_SEPARATOR) { return $this->root; } else { $path = $this->_normpath($path); if (strpos($path, $this->systemRoot) === 0) { return $path; } else if (DIRECTORY_SEPARATOR !== '/' && preg_match('/^[a-zA-Z]:' . preg_quote(DIRECTORY_SEPARATOR, '/') . '/', $path)) { return $path; } else { return $this->_joinPath($this->root, $path); } } } /** * Return fake path started from root dir * * @param string $path file path * * @return string * @author Dmitry (dio) Levashov **/ protected function _path($path) { return $this->rootName . ($path == $this->root ? '' : $this->separator . $this->_relpath($path)); } /** * Return true if $path is children of $parent * * @param string $path path to check * @param string $parent parent path * * @return bool * @author Dmitry (dio) Levashov **/ protected function _inpath($path, $parent) { $cwd = getcwd(); $real_path = $this->getFullPath($path, $cwd); $real_parent = $this->getFullPath($parent, $cwd); if ($real_path && $real_parent) { return $real_path === $real_parent || strpos($real_path, rtrim($real_parent, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR) === 0; } return false; } /***************** file stat ********************/ /** * Return stat for given path. * Stat contains following fields: * - (int) size file size in b. required * - (int) ts file modification time in unix time. required * - (string) mime mimetype. required for folders, others - optionally * - (bool) read read permissions. required * - (bool) write write permissions. required * - (bool) locked is object locked. optionally * - (bool) hidden is object hidden. optionally * - (string) alias for symlinks - link target path relative to root path. optionally * - (string) target for symlinks - link target path. optionally * If file does not exists - returns empty array or false. * * @param string $path file path * * @return array|false * @author Dmitry (dio) Levashov **/ protected function _stat($path) { $stat = array(); if (!file_exists($path) && !is_link($path)) { return $stat; } //Verifies the given path is the root or is inside the root. Prevents directory traveral. if (!$this->_inpath($path, $this->root)) { return $stat; } $stat['isowner'] = false; $linkreadable = false; if ($path != $this->root && is_link($path)) { if (!$this->options['followSymLinks']) { return array(); } if (!($target = $this->readlink($path)) || $target == $path) { if (is_null($target)) { $stat = array(); return $stat; } else { $stat['mime'] = 'symlink-broken'; $target = readlink($path); $lstat = lstat($path); $ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']); $linkreadable = !empty($ostat['isowner']); } } $stat['alias'] = $this->_path($target); $stat['target'] = $target; } $readable = is_readable($path); if ($readable) { $size = sprintf('%u', filesize($path)); $stat['ts'] = filemtime($path); if ($this->statOwner) { $fstat = stat($path); $uid = $fstat['uid']; $gid = $fstat['gid']; $stat['perm'] = substr((string)decoct($fstat['mode']), -4); $stat = array_merge($stat, $this->getOwnerStat($uid, $gid)); } } if (($dir = is_dir($path)) && $this->options['detectDirIcon']) { $favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon']; if ($this->URL && file_exists($favicon)) { $stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1)); } } if (!isset($stat['mime'])) { $stat['mime'] = $dir ? 'directory' : $this->mimetype($path); } //logical rights first $stat['read'] = ($linkreadable || $readable) ? null : false; $stat['write'] = is_writable($path) ? null : false; if (is_null($stat['read'])) { if ($dir) { $stat['size'] = 0; } else if (isset($size)) { $stat['size'] = $size; } } if ($this->options['statCorrector']) { call_user_func_array($this->options['statCorrector'], array(&$stat, $path, $this->statOwner, $this)); } return $stat; } /** * Get stat `owner`, `group` and `isowner` by `uid` and `gid` * Sub-fuction of _stat() and _scandir() * * @param integer $uid * @param integer $gid * * @return array stat */ protected function getOwnerStat($uid, $gid) { static $names = null; static $phpuid = null; if (is_null($names)) { $names = array('uid' => array(), 'gid' => array()); } if (is_null($phpuid)) { if (is_callable('posix_getuid')) { $phpuid = posix_getuid(); } else { $phpuid = 0; } } $stat = array(); if ($uid) { $stat['isowner'] = ($phpuid == $uid); if (isset($names['uid'][$uid])) { $stat['owner'] = $names['uid'][$uid]; } else if (is_callable('posix_getpwuid')) { $pwuid = posix_getpwuid($uid); $stat['owner'] = $names['uid'][$uid] = $pwuid['name']; } else { $stat['owner'] = $names['uid'][$uid] = $uid; } } if ($gid) { if (isset($names['gid'][$gid])) { $stat['group'] = $names['gid'][$gid]; } else if (is_callable('posix_getgrgid')) { $grgid = posix_getgrgid($gid); $stat['group'] = $names['gid'][$gid] = $grgid['name']; } else { $stat['group'] = $names['gid'][$gid] = $gid; } } return $stat; } /** * Return true if path is dir and has at least one childs directory * * @param string $path dir path * * @return bool * @author Dmitry (dio) Levashov **/ protected function _subdirs($path) { $dirs = false; if (is_dir($path) && is_readable($path)) { if (class_exists('FilesystemIterator', false)) { $dirItr = new ParentIterator( new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS | FilesystemIterator::CURRENT_AS_SELF | (defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') ? RecursiveDirectoryIterator::FOLLOW_SYMLINKS : 0) ) ); $dirItr->rewind(); if ($dirItr->hasChildren()) { $dirs = true; $name = $dirItr->getSubPathName(); while ($dirItr->valid()) { if (!$this->attr($path . DIRECTORY_SEPARATOR . $name, 'read', null, true)) { $dirs = false; $dirItr->next(); $name = $dirItr->getSubPathName(); continue; } $dirs = true; break; } } } else { $path = strtr($path, array('[' => '\\[', ']' => '\\]', '*' => '\\*', '?' => '\\?')); return (bool)glob(rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR); } } return $dirs; } /** * Return object width and height * Usualy used for images, but can be realize for video etc... * * @param string $path file path * @param string $mime file mime type * * @return string * @author Dmitry (dio) Levashov **/ protected function _dimensions($path, $mime) { clearstatcache(); return strpos($mime, 'image') === 0 && is_readable($path) && filesize($path) && ($s = getimagesize($path)) !== false ? $s[0] . 'x' . $s[1] : false; } /******************** file/dir content *********************/ /** * Return symlink target file * * @param string $path link path * * @return string * @author Dmitry (dio) Levashov **/ protected function readlink($path) { if (!($target = readlink($path))) { return null; } if (strpos($target, $this->systemRoot) !== 0) { $target = $this->_joinPath(dirname($path), $target); } if (!file_exists($target)) { return false; } return $target; } /** * Return files list in directory. * * @param string $path dir path * * @return array * @throws elFinderAbortException * @author Dmitry (dio) Levashov */ protected function _scandir($path) { elFinder::checkAborted(); $files = array(); $cache = array(); $dirWritable = is_writable($path); $dirItr = array(); $followSymLinks = $this->options['followSymLinks']; try { $dirItr = new DirectoryIterator($path); } catch (UnexpectedValueException $e) { } foreach ($dirItr as $file) { try { if ($file->isDot()) { continue; } $files[] = $fpath = $file->getPathname(); $br = false; $stat = array(); $stat['isowner'] = false; $linkreadable = false; if ($file->isLink()) { if (!$followSymLinks) { continue; } if (!($target = $this->readlink($fpath)) || $target == $fpath) { if (is_null($target)) { $stat = array(); $br = true; } else { $_path = $fpath; $stat['mime'] = 'symlink-broken'; $target = readlink($_path); $lstat = lstat($_path); $ostat = $this->getOwnerStat($lstat['uid'], $lstat['gid']); $linkreadable = !empty($ostat['isowner']); $dir = false; $stat['alias'] = $this->_path($target); $stat['target'] = $target; } } else { $dir = is_dir($target); $stat['alias'] = $this->_path($target); $stat['target'] = $target; $stat['mime'] = $dir ? 'directory' : $this->mimetype($stat['alias']); } } else { if (($dir = $file->isDir()) && $this->options['detectDirIcon']) { $path = $file->getPathname(); $favicon = $path . DIRECTORY_SEPARATOR . $this->options['detectDirIcon']; if ($this->URL && file_exists($favicon)) { $stat['icon'] = $this->URL . str_replace(DIRECTORY_SEPARATOR, '/', substr($favicon, strlen($this->root) + 1)); } } $stat['mime'] = $dir ? 'directory' : $this->mimetype($fpath); } $size = sprintf('%u', $file->getSize()); $stat['ts'] = $file->getMTime(); if (!$br) { if ($this->statOwner && !$linkreadable) { $uid = $file->getOwner(); $gid = $file->getGroup(); $stat['perm'] = substr((string)decoct($file->getPerms()), -4); $stat = array_merge($stat, $this->getOwnerStat($uid, $gid)); } //logical rights first $stat['read'] = ($linkreadable || $file->isReadable()) ? null : false; $stat['write'] = $file->isWritable() ? null : false; $stat['locked'] = $dirWritable ? null : true; if (is_null($stat['read'])) { $stat['size'] = $dir ? 0 : $size; } if ($this->options['statCorrector']) { call_user_func_array($this->options['statCorrector'], array(&$stat, $fpath, $this->statOwner, $this)); } } $cache[] = array($fpath, $stat); } catch (RuntimeException $e) { continue; } } if ($cache) { $cache = $this->convEncOut($cache, false); foreach ($cache as $d) { $this->updateCache($d[0], $d[1]); } } return $files; } /** * Open file and return file pointer * * @param string $path file path * @param string $mode * * @return false|resource * @internal param bool $write open file for writing * @author Dmitry (dio) Levashov */ protected function _fopen($path, $mode = 'rb') { return fopen($path, $mode); } /** * Close opened file * * @param resource $fp file pointer * @param string $path * * @return bool * @author Dmitry (dio) Levashov */ protected function _fclose($fp, $path = '') { return (is_resource($fp) && fclose($fp)); } /******************** file/dir manipulations *************************/ /** * Create dir and return created dir path or false on failed * * @param string $path parent dir path * @param string $name new directory name * * @return string|bool * @author Dmitry (dio) Levashov **/ protected function _mkdir($path, $name) { $path = $this->_joinPath($path, $name); if (mkdir($path)) { chmod($path, $this->options['dirMode']); return $path; } return false; } /** * Create file and return it's path or false on failed * * @param string $path parent dir path * @param string $name new file name * * @return string|bool * @author Dmitry (dio) Levashov **/ protected function _mkfile($path, $name) { $path = $this->_joinPath($path, $name); if (($fp = fopen($path, 'w'))) { fclose($fp); chmod($path, $this->options['fileMode']); return $path; } return false; } /** * Create symlink * * @param string $source file to link to * @param string $targetDir folder to create link in * @param string $name symlink name * * @return bool * @author Dmitry (dio) Levashov **/ protected function _symlink($source, $targetDir, $name) { return $this->localFileSystemSymlink($source, $this->_joinPath($targetDir, $name)); } /** * Copy file into another file * * @param string $source source file path * @param string $targetDir target directory path * @param string $name new file name * * @return bool * @author Dmitry (dio) Levashov **/ protected function _copy($source, $targetDir, $name) { $mtime = filemtime($source); $target = $this->_joinPath($targetDir, $name); if ($ret = copy($source, $target)) { isset($this->options['keepTimestamp']['copy']) && $mtime && touch($target, $mtime); } return $ret; } /** * Move file into another parent dir. * Return new file path or false. * * @param string $source source file path * @param $targetDir * @param string $name file name * * @return bool|string * @internal param string $target target dir path * @author Dmitry (dio) Levashov */ protected function _move($source, $targetDir, $name) { $mtime = filemtime($source); $target = $this->_joinPath($targetDir, $name); if ($ret = rename($source, $target) ? $target : false) { isset($this->options['keepTimestamp']['move']) && $mtime && touch($target, $mtime); } return $ret; } /** * Remove file * * @param string $path file path * * @return bool * @author Dmitry (dio) Levashov **/ protected function _unlink($path) { return is_file($path) && unlink($path); } /** * Remove dir * * @param string $path dir path * * @return bool * @author Dmitry (dio) Levashov **/ protected function _rmdir($path) { return rmdir($path); } /** * Create new file and write into it from file pointer. * Return new file path or false on error. * * @param resource $fp file pointer * @param string $dir target dir path * @param string $name file name * @param array $stat file stat (required by some virtual fs) * * @return bool|string * @author Dmitry (dio) Levashov **/ protected function _save($fp, $dir, $name, $stat) { $path = $this->_joinPath($dir, $name); $meta = stream_get_meta_data($fp); $uri = isset($meta['uri']) ? $meta['uri'] : ''; if ($uri && !preg_match('#^[a-zA-Z0-9]+://#', $uri) && !is_link($uri)) { fclose($fp); $mtime = filemtime($uri); $isCmdPaste = ($this->ARGS['cmd'] === 'paste'); $isCmdCopy = ($isCmdPaste && empty($this->ARGS['cut'])); if (($isCmdCopy || !rename($uri, $path)) && !copy($uri, $path)) { return false; } // keep timestamp on upload if ($mtime && $this->ARGS['cmd'] === 'upload') { touch($path, isset($this->options['keepTimestamp']['upload']) ? $mtime : time()); } } else { if (file_put_contents($path, $fp, LOCK_EX) === false) { return false; } } chmod($path, $this->options['fileMode']); return $path; } /** * Get file contents * * @param string $path file path * * @return string|false * @author Dmitry (dio) Levashov **/ protected function _getContents($path) { return file_get_contents($path); } /** * Write a string to a file * * @param string $path file path * @param string $content new file content * * @return bool * @author Dmitry (dio) Levashov **/ protected function _filePutContents($path, $content) { return (file_put_contents($path, $content, LOCK_EX) !== false); } /** * Detect available archivers * * @return void * @throws elFinderAbortException */ protected function _checkArchivers() { $this->archivers = $this->getArchivers(); return; } /** * chmod availability * * @param string $path * @param string $mode * * @return bool */ protected function _chmod($path, $mode) { $modeOct = is_string($mode) ? octdec($mode) : octdec(sprintf("%04o", $mode)); return chmod($path, $modeOct); } /** * Recursive symlinks search * * @param string $path file/dir path * * @return bool * @throws Exception * @author Dmitry (dio) Levashov */ protected function _findSymlinks($path) { return self::localFindSymlinks($path); } /** * Extract files from archive * * @param string $path archive path * @param array $arc archiver command and arguments (same as in $this->archivers) * * @return array|string|boolean * @throws elFinderAbortException * @author Dmitry (dio) Levashov, * @author Alexey Sukhotin */ protected function _extract($path, $arc) { if ($this->quarantine) { $dir = $this->quarantine . DIRECTORY_SEPARATOR . md5(basename($path) . mt_rand()); $archive = (isset($arc['toSpec']) || $arc['cmd'] === 'phpfunction') ? '' : $dir . DIRECTORY_SEPARATOR . basename($path); if (!mkdir($dir)) { return false; } // insurance unexpected shutdown register_shutdown_function(array($this, 'rmdirRecursive'), realpath($dir)); chmod($dir, 0777); // copy in quarantine if (!is_readable($path) || ($archive && !copy($path, $archive))) { return false; } // extract in quarantine try { $this->unpackArchive($path, $arc, $archive ? true : $dir); } catch(Exception $e) { return $this->setError($e->getMessage()); } // get files list try { $ls = self::localScandir($dir); } catch (Exception $e) { return false; } // no files - extract error ? if (empty($ls)) { return false; } $this->archiveSize = 0; // find symlinks and check extracted items $checkRes = $this->checkExtractItems($dir); if ($checkRes['symlinks']) { self::localRmdirRecursive($dir); return $this->setError(array_merge($this->error, array(elFinder::ERROR_ARC_SYMLINKS))); } $this->archiveSize = $checkRes['totalSize']; if ($checkRes['rmNames']) { foreach ($checkRes['rmNames'] as $name) { $this->addError(elFinder::ERROR_SAVE, $name); } } // check max files size if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $this->archiveSize) { $this->delTree($dir); return $this->setError(elFinder::ERROR_ARC_MAXSIZE); } $extractTo = $this->extractToNewdir; // 'auto', ture or false // archive contains one item - extract in archive dir $name = ''; $src = $dir . DIRECTORY_SEPARATOR . $ls[0]; if (($extractTo === 'auto' || !$extractTo) && count($ls) === 1 && is_file($src)) { $name = $ls[0]; } else if ($extractTo === 'auto' || $extractTo) { // for several files - create new directory // create unique name for directory $src = $dir; $splits = elFinder::splitFileExtention(basename($path)); $name = $splits[0]; $test = dirname($path) . DIRECTORY_SEPARATOR . $name; if (file_exists($test) || is_link($test)) { $name = $this->uniqueName(dirname($path), $name, '-', false); } } if ($name !== '') { $result = dirname($path) . DIRECTORY_SEPARATOR . $name; if (!rename($src, $result)) { $this->delTree($dir); return false; } } else { $dstDir = dirname($path); $result = array(); foreach ($ls as $name) { $target = $dstDir . DIRECTORY_SEPARATOR . $name; if (self::localMoveRecursive($dir . DIRECTORY_SEPARATOR . $name, $target, true, $this->options['copyJoin'])) { $result[] = $target; } } if (!$result) { $this->delTree($dir); return false; } } is_dir($dir) && $this->delTree($dir); return (is_array($result) || file_exists($result)) ? $result : false; } //TODO: Add return statement here return false; } /** * Create archive and return its path * * @param string $dir target dir * @param array $files files names list * @param string $name archive name * @param array $arc archiver options * * @return string|bool * @throws elFinderAbortException * @author Dmitry (dio) Levashov, * @author Alexey Sukhotin */ protected function _archive($dir, $files, $name, $arc) { return $this->makeArchive($dir, $files, $name, $arc); } /******************** Over write functions *************************/ /** * File path of local server side work file path * * @param string $path * * @return string * @author Naoki Sawada */ protected function getWorkFile($path) { return $path; } /** * Delete dirctory trees * * @param string $localpath path need convert encoding to server encoding * * @return boolean * @throws elFinderAbortException * @author Naoki Sawada */ protected function delTree($localpath) { return $this->rmdirRecursive($localpath); } /** * Return fileinfo based on filename * For item ID based path file system * Please override if needed on each drivers * * @param string $path file cache * * @return array|boolean false */ protected function isNameExists($path) { $exists = file_exists($this->convEncIn($path)); // restore locale $this->convEncOut(); return $exists ? $this->stat($path) : false; } /******************** Over write (Optimized) functions *************************/ /** * Recursive files search * * @param string $path dir path * @param string $q search string * @param array $mimes * * @return array * @throws elFinderAbortException * @author Dmitry (dio) Levashov * @author Naoki Sawada */ protected function doSearch($path, $q, $mimes) { if (!empty($this->doSearchCurrentQuery['matchMethod']) || $this->encoding || !class_exists('FilesystemIterator', false)) { // has custom match method or non UTF-8, use elFinderVolumeDriver::doSearch() return parent::doSearch($path, $q, $mimes); } $result = array(); $timeout = $this->options['searchTimeout'] ? $this->searchStart + $this->options['searchTimeout'] : 0; if ($timeout && $timeout < time()) { $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($path))); return $result; } elFinder::extendTimeLimit($this->options['searchTimeout'] + 30); $match = array(); try { $iterator = new RecursiveIteratorIterator( new RecursiveCallbackFilterIterator( new RecursiveDirectoryIterator($path, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::SKIP_DOTS | ((defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') && $this->options['followSymLinks']) ? RecursiveDirectoryIterator::FOLLOW_SYMLINKS : 0) ), array($this, 'localFileSystemSearchIteratorFilter') ), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD ); foreach ($iterator as $key => $node) { if ($timeout && ($this->error || $timeout < time())) { !$this->error && $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($node->getPath))); break; } if ($node->isDir()) { if ($this->stripos($node->getFilename(), $q) !== false) { $match[] = $key; } } else { $match[] = $key; } } } catch (Exception $e) { } if ($match) { foreach ($match as $p) { if ($timeout && ($this->error || $timeout < time())) { !$this->error && $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode(dirname($p)))); break; } $stat = $this->stat($p); if (!$stat) { // invalid links continue; } if (!empty($stat['hidden']) || !$this->mimeAccepted($stat['mime'], $mimes)) { continue; } if ((!$mimes || $stat['mime'] !== 'directory')) { $stat['path'] = $this->path($stat['hash']); if ($this->URL && !isset($stat['url'])) { $_path = str_replace(DIRECTORY_SEPARATOR, '/', substr($p, strlen($this->root) + 1)); $stat['url'] = $this->URL . str_replace('%2F', '/', rawurlencode($_path)); } $result[] = $stat; } } } return $result; } /******************** Original local functions ************************ * * @param $file * @param $key * @param $iterator * * @return bool */ public function localFileSystemSearchIteratorFilter($file, $key, $iterator) { /* @var FilesystemIterator $file */ /* @var RecursiveDirectoryIterator $iterator */ $name = $file->getFilename(); if ($this->doSearchCurrentQuery['excludes']) { foreach ($this->doSearchCurrentQuery['excludes'] as $exclude) { if ($this->stripos($name, $exclude) !== false) { return false; } } } if ($iterator->hasChildren()) { if ($this->options['searchExDirReg'] && preg_match($this->options['searchExDirReg'], $key)) { return false; } return (bool)$this->attr($key, 'read', null, true); } return ($this->stripos($name, $this->doSearchCurrentQuery['q']) === false) ? false : true; } /** * Creates a symbolic link * * @param string $target The target * @param string $link The link * * @return boolean ( result of symlink() ) */ protected function localFileSystemSymlink($target, $link) { $res = false; if (function_exists('symlink') and is_callable('symlink')) { $errlev = error_reporting(); error_reporting($errlev ^ E_WARNING); if ($res = symlink(realpath($target), $link)) { $res = is_readable($link); } error_reporting($errlev); } return $res; } } // END class js/0_utilities.js 0000666 00000002303 15226760542 0007763 0 ustar 00 (function ( $ ) { $.neveCustomizeUtilities = { 'setLiveCss': function ( settings, to ) { 'use strict'; var result = ''; var styleClass = $( '.' + settings.styleClass ); if ( typeof to !== 'object' ) { $( settings.selectors ).css( settings.cssProperty, to.toString() + settings.propertyUnit ); return false; } $.each( to, function ( key, value ) { var style_to_add; if ( key === 'suffix' ) { return true; } var unit = settings.propertyUnit; if ( typeof settings.propertyUnit === 'object' ) { unit = settings.propertyUnit[ key ]; } style_to_add = settings.selectors + '{ ' + settings.cssProperty + ':' + value + unit + '}'; switch ( key ) { default: case 'mobile': result += style_to_add; break; case 'desktop': result += '@media(min-width: 960px) {' + style_to_add + '}'; break; case 'tablet': result += '@media (min-width: 576px){' + style_to_add + '}'; break; } } ); if ( styleClass.length > 0 ) { styleClass.text( result ); } else { $( 'head' ).append( '<style type="text/css" class="' + settings.styleClass + '">' + result + '</style>' ); } } }; }( jQuery )); js/2_layout.js 0000666 00000005520 15226760542 0007273 0 ustar 00 /** * Handle the layout preview. */ (function ( $ ) { $.neveLayoutPreview = { /** * Initialize the layout preview functions. */ init: function () { this.contentWidthsPreview(); this.containersLivePreview(); }, /** * Define content width controls and correspondent properties. */ contentWidths: { 'neve_sitewide_content_width': { content: '.neve-main > .container .col, .neve-main > .container-fluid .col', sidebar: '.nv-sidebar-wrap' }, 'neve_blog_archive_content_width': { content: '.archive-container .nv-index-posts', sidebar: '.archive-container .nv-sidebar-wrap' }, 'neve_single_post_content_width': { content: '.single-post-container .nv-single-post-wrap', sidebar: '.single-post-container .nv-sidebar-wrap' }, 'neve_shop_archive_content_width': { content: '.archive.woocommerce .shop-container .nv-shop.col', sidebar: '.archive.woocommerce .shop-container .nv-sidebar-wrap' }, 'neve_single_product_content_width': { content: '.single-product .shop-container .nv-shop.col', sidebar: '.single-product .shop-container .nv-sidebar-wrap' }, 'neve_other_pages_content_width': { content: 'body:not(.single):not(.archive):not(.blog):not(.search) .neve-main > .container .col', sidebar: 'body:not(.single):not(.archive):not(.blog):not(.search) .nv-sidebar-wrap' }, }, /** * Run the content width previews. */ contentWidthsPreview: function () { $.each( this.contentWidths, function ( id, args ) { wp.customize( id, function ( value ) { value.bind( function ( newval ) { jQuery( args.content ).css( 'max-width', newval + '%' ); jQuery( args.sidebar ).css( 'max-width', 100 - newval + '%' ); } ); } ); } ); }, /** * Define container theme mods and correspondent selectors. */ containersLayoutMap: { 'neve_default_container_style': '.page:not(.woocommerce) .single-page-container', 'neve_blog_archive_container_style': '.archive-container', 'neve_single_post_container_style': '.single-post-container', 'neve_shop_archive_container_style': '.woocommerce-page.post-type-archive .neve-main > div', 'neve_single_product_container_style': '.single-product .neve-main > div', }, /** * Run the containers live preview. */ containersLivePreview: function () { 'use strict'; $.each( this.containersLayoutMap, function ( controlId, cssSelector ) { cssSelector += ':not(.set-in-metabox)'; wp.customize( controlId, function ( value ) { value.bind( function ( newval ) { if ( newval === 'contained' ) { $( cssSelector ).removeClass( 'container-fluid' ).addClass( 'container' ); return false; } $( cssSelector ).removeClass( 'container' ).addClass( 'container-fluid' ); } ); } ); } ); }, }; })( jQuery ); jQuery.neveLayoutPreview.init(); colors_background.php 0000666 00000011503 15226760542 0010772 0 ustar 00 <?php /** * Colors / Background section. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 20/08/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Section; /** * Class Colors_Background * * @package Neve\Customizer\Options */ class Colors_Background extends Base_Customizer { const CUSTOM_COLOR_LIMIT = 30; const CUSTOM_COLOR_LABEL_MAX_LENGTH = 16; /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { $this->wpc->remove_control( 'background_color' ); $this->section_colors_background(); $this->controls_colors(); } /** * Add customize section */ private function section_colors_background() { $this->add_section( new Section( 'neve_colors_background_section', array( 'priority' => 27, 'title' => esc_html__( 'Colors & Background', 'neve' ), ) ) ); } /** * Add colors controls. */ private function controls_colors() { $this->add_global_colors(); } /** * Change controls. */ public function change_controls() { $priority = 30; $controls_to_move = array( 'background_image', 'background_preset', 'background_position', 'background_size', 'background_repeat', 'background_attachment', ); foreach ( $controls_to_move as $control_slug ) { $control = $this->get_customizer_object( 'control', $control_slug ); $control->priority = $priority; $control->section = 'neve_colors_background_section'; $priority += 5; } } /** * Add global colors. */ private function add_global_colors() { $this->add_control( new Control( 'neve_global_colors', [ 'sanitize_callback' => [ $this, 'sanitize_global_colors' ], 'default' => neve_get_global_colors_default( true ), 'transport' => 'postMessage', ], [ 'label' => __( 'Global Colors', 'neve' ), 'priority' => 10, 'section' => 'neve_colors_background_section', 'type' => 'neve_global_colors', 'default_values' => neve_get_global_colors_default(), 'input_attrs' => [ 'link' => [ 'url' => esc_url( 'https://docs.themeisle.com/article/1314-global-colors-in-neve' ), 'string' => esc_html__( 'How the color system works', 'neve' ), 'new_tab' => true, ], ], 'live_refresh_selector' => true, ], 'Neve\Customizer\Controls\React\Global_Colors' ) ); $this->add_control( new Control( 'neve_global_custom_colors', [ 'sanitize_callback' => [ $this, 'sanitize_global_custom_colors' ], 'default' => [], 'transport' => 'refresh', ], [ 'label' => __( 'Custom Colors', 'neve' ), 'priority' => 10, 'section' => 'neve_colors_background_section', 'type' => 'neve_global_custom_colors', 'default_values' => [], 'live_refresh_selector' => true, ], 'Neve\Customizer\Controls\React\Global_Custom_Colors' ) ); } /** * Sanitize Global Colors Setting * * @param array $value recieved value. * @return array */ public function sanitize_global_colors( $value ) { // `flag` key is used to trigger setting change on deep state changes inside the palettes. if ( isset( $value['flag'] ) ) { unset( $value['flag'] ); } $default = neve_get_global_colors_default(); if ( ! isset( $value['activePalette'] ) || ! isset( $value['palettes'] ) ) { return $default; } foreach ( $value['palettes'] as $slug => $args ) { foreach ( $args['colors'] as $key => $color_val ) { $value['palettes'][ $slug ]['colors'][ $key ] = neve_sanitize_colors( $color_val ); } } return $value; } /** * Sanitize Global Custom Colors Setting * * @param array $value recieved value. * @return array */ public function sanitize_global_custom_colors( $value ) { // `flag` key is used to trigger setting change on deep state changes inside the palettes. if ( isset( $value['flag'] ) ) { unset( $value['flag'] ); } if ( count( $value ) > self::CUSTOM_COLOR_LIMIT ) { $value = array_slice( $value, 0, self::CUSTOM_COLOR_LIMIT ); } foreach ( $value as $slug => $options ) { $color = neve_sanitize_colors( $options['val'] ); if ( ! $color ) { unset( $value[ $slug ] ); continue; } $label = sanitize_text_field( $options['label'] ); if ( strlen( $label ) > self::CUSTOM_COLOR_LABEL_MAX_LENGTH ) { $label = substr( $label, 0, self::CUSTOM_COLOR_LABEL_MAX_LENGTH ); } $value[ $slug ]['label'] = $label; $value[ $slug ]['val'] = $color; } return $value; } } checkout.php 0000666 00000005651 15226760542 0007106 0 ustar 00 <?php /** * Customizer checkout controls. * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Types\Section; use Neve\Customizer\Types\Control; /** * Class Checkout * * @package Neve\Customizer\Options */ class Checkout extends Base_Customizer { /** * Init function * * @return bool|void */ public function init() { if ( defined( 'NEVE_PRO_VERSION' ) ) { return false; } parent::init(); } /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { $this->group_controls(); } /** * Change the controls added from WooCommerce. */ public function change_controls() { $changes = [ 'woocommerce_checkout_company_field' => [ 'priority' => 110 ], 'woocommerce_checkout_address_2_field' => [ 'priority' => 120 ], 'woocommerce_checkout_phone_field' => [ 'priority' => 130 ], 'woocommerce_checkout_highlight_required_fields' => [ 'priority' => 140, 'type' => 'neve_toggle_control', ], 'wp_page_for_privacy_policy' => [ 'priority' => 190 ], 'woocommerce_terms_page_id' => [ 'priority' => 200 ], 'woocommerce_checkout_privacy_policy_text' => [ 'priority' => 210 ], 'woocommerce_checkout_terms_and_conditions_checkbox_text' => [ 'priority' => 220 ], ]; foreach ( $changes as $control_slug => $props ) { foreach ( $props as $prop => $new_value ) { $this->change_customizer_object( 'control', $control_slug, $prop, $new_value ); } } } /** * Add control groups to better organize the customizer. */ private function group_controls() { $checkout_section = $this->wpc->get_section( 'woocommerce_checkout' ); $this->wpc->add_section( $checkout_section ); $this->add_control( new Control( 'neve_checkout_settings_heading', array( 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ), array( 'label' => esc_html__( 'Checkout Style', 'neve' ), 'section' => 'woocommerce_checkout', 'priority' => 0, 'class' => 'neve-checkout-accordion', 'accordion' => true, 'controls_to_wrap' => 1, 'expanded' => true, ), 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_woo_checkout_settings_heading', array( 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ), array( 'label' => esc_html__( 'General', 'neve' ), 'section' => 'woocommerce_checkout', 'priority' => 100, 'class' => 'woo-checkout-accordion', 'accordion' => true, 'controls_to_wrap' => 7, 'expanded' => true, ), 'Neve\Customizer\Controls\Heading' ) ); } } layout_sidebar.php 0000666 00000022425 15226760542 0010305 0 ustar 00 <?php /** * Sidebar layout section. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 20/08/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Defaults\Layout; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Section; /** * Class Layout_Sidebar * * @package Neve\Customizer\Options */ class Layout_Sidebar extends Base_Customizer { use Layout; /** * Advanced controls. * * @var array */ private $advanced_controls = []; /** * Layout_Sidebar constructor. */ public function __construct() { $this->advanced_controls = [ 'blog_archive' => __( 'Blog / Archive', 'neve' ), 'single_post' => __( 'Single Post', 'neve' ), ]; $this->add_woocommerce_controls(); $this->advanced_controls['other_pages'] = __( 'Others', 'neve' ); } /** * Add woo controls. */ private function add_woocommerce_controls() { if ( ! class_exists( 'WooCommerce', false ) ) { return; } $this->advanced_controls = array_merge( $this->advanced_controls, [ 'shop_archive' => __( 'Shop / Archive', 'neve' ), 'single_product' => __( 'Single Product', 'neve' ), ] ); } /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { $this->section_sidebar(); $this->add_main_controls(); $this->add_advanced_controls(); } /** * Add customize section */ private function section_sidebar() { $this->add_section( new Section( 'neve_sidebar', array( 'priority' => 30, 'title' => esc_html__( 'Content / Sidebar', 'neve' ), 'panel' => 'neve_layout', ) ) ); } /** * Site-wide controls that will affect all pages. */ private function add_main_controls() { $this->add_control( new Control( 'neve_default_sidebar_layout', array( 'sanitize_callback' => array( $this, 'sanitize_sidebar_layout' ), 'default' => 'right', ), array( 'label' => __( 'Sitewide Sidebar Layout', 'neve' ), 'section' => 'neve_sidebar', 'priority' => 10, 'choices' => $this->sidebar_layout_choices( 'neve_default_sidebar_layout' ), 'active_callback' => array( $this, 'sidewide_options_active_callback' ), ), '\Neve\Customizer\Controls\React\Radio_Image' ) ); $this->add_control( new Control( 'neve_sitewide_content_width', [ 'sanitize_callback' => 'absint', 'transport' => $this->selective_refresh, 'default' => 70, ], [ 'label' => esc_html__( 'Sitewide Content Width (%)', 'neve' ), 'section' => 'neve_sidebar', 'type' => 'neve_range_control', 'input_attrs' => [ 'min' => 50, 'max' => 100, 'defaultVal' => 70, ], 'priority' => 20, 'active_callback' => [ $this, 'sidewide_options_active_callback' ], ], 'Neve\Customizer\Controls\React\Range' ) ); $this->add_control( new Control( 'neve_advanced_layout_options', array( 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => true, ), array( 'label' => esc_html__( 'Enable Advanced Options', 'neve' ), 'section' => 'neve_sidebar', 'type' => 'neve_toggle_control', 'priority' => 30, ) ) ); } /** * Get the sidebar layout choices. * * @param string $control_id Name of the control. * * @return array */ private function sidebar_layout_choices( $control_id ) { $options = apply_filters( 'neve_sidebar_layout_choices', array( 'full-width' => array( 'name' => __( 'Full Width', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqAQMAAABknzrDAAAABlBMVEX////V1dXUdjOkAAAAPUlEQVRIx2NgGAUkAcb////Y/+d/+P8AdcQoc8vhH/X/5P+j2kG+GA3CCgrwi43aMWrHqB2jdowEO4YpAACyKSE0IzIuBgAAAABJRU5ErkJggg==', ), 'left' => array( 'name' => __( 'Left', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqAgMAAAAjP0ATAAAACVBMVEX///8+yP/V1dXG9YqxAAAAWElEQVR42mNgGAXDE4RCQMDAKONaBQINWqtWrWBatQDIaxg8ygYqQIAOYwC6bwHUmYNH2eBPSMhgBQXKRr0w6oVRL4x6YdQLo14Y9cKoF0a9QCO3jYLhBADvmFlNY69qsQAAAABJRU5ErkJggg==', ), 'right' => array( 'name' => __( 'Right', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqAgMAAAAjP0ATAAAACVBMVEX///8+yP/V1dXG9YqxAAAAWUlEQVR42mNgGAUjB4iGgkEIzZStAoEVTECiQWsVkLdiECkboAABOmwBF9BtUGcOImUDEiCkJCQU0ECBslEvjHph1AujXhj1wqgXRr0w6oVRLwyEF0bBUAUAz/FTNXm+R/MAAAAASUVORK5CYII=', ), ), $control_id ); foreach ( $options as $slug => $args ) { if ( ! isset( $args['name'] ) ) { $options[ $slug ]['name'] = ucwords( str_replace( '-', ' ', $slug ) ); } } return $options; } /** * Advanced controls. */ private function add_advanced_controls() { $priority = 40; /** * Filters the sidebar advanced controls. * * @param array $advanced_controls Container style controls. * * @since 3.1.0 */ $this->advanced_controls = apply_filters( 'neve_sidebar_controls_filter', $this->advanced_controls ); foreach ( $this->advanced_controls as $id => $heading_label ) { $heading_id = 'neve_' . $id . '_heading'; $layout_id = 'neve_' . $id . '_sidebar_layout'; $width_id = 'neve_' . $id . '_content_width'; $this->add_control( new Control( $heading_id, array( 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ), array( 'label' => $heading_label, 'section' => 'neve_sidebar', 'priority' => $priority, 'class' => esc_attr( 'advanced-sidebar-accordion-' . $heading_id ), 'accordion' => true, 'controls_to_wrap' => 2, 'expanded' => ( $priority === 40 ), // true or false 'active_callback' => array( $this, 'advanced_options_active_callback' ), ), 'Neve\Customizer\Controls\Heading' ) ); $priority += 30; $this->add_control( new Control( $layout_id, array( 'sanitize_callback' => array( $this, 'sanitize_sidebar_layout' ), 'default' => $this->sidebar_layout_alignment_default( $layout_id ), ), array( 'label' => __( 'Sidebar Layout', 'neve' ), 'description' => $this->get_sidebar_control_description( $layout_id ), 'section' => 'neve_sidebar', 'priority' => $priority, 'choices' => $this->sidebar_layout_choices( $layout_id ), 'active_callback' => array( $this, 'advanced_options_active_callback' ), ), '\Neve\Customizer\Controls\React\Radio_Image' ) ); $priority += 30; $width_default = $this->sidebar_layout_width_default( $width_id ); $this->add_control( new Control( $width_id, array( 'sanitize_callback' => 'absint', 'transport' => $this->selective_refresh, 'default' => $width_default, ), array( 'label' => esc_html__( 'Content Width (%)', 'neve' ), 'section' => 'neve_sidebar', 'type' => 'neve_range_control', 'input_attrs' => [ 'min' => 50, 'max' => 100, 'defaultVal' => $width_default, ], 'priority' => $priority, 'active_callback' => array( $this, 'advanced_options_active_callback' ), ), 'Neve\Customizer\Controls\React\Range' ) ); $priority += 30; } } /** * Get the description for sidebar position. * * @param string $control_id Control id. * * @return string */ private function get_sidebar_control_description( $control_id ) { if ( $control_id !== 'neve_shop_archive_sidebar_layout' ) { return ''; } $shop_id = get_option( 'woocommerce_shop_page_id' ); if ( empty( $shop_id ) ) { return ''; } $meta = get_post_meta( $shop_id, 'neve_meta_sidebar', true ); if ( empty( $meta ) || $meta === 'default' ) { return ''; } /* translators: %s is Notice text */ $template = '<p class="notice notice-info">%s</p>'; return sprintf( $template, sprintf( /* translators: %s is edit page link */ esc_html__( 'Note: It seems that the shop page has an individual sidebar layout already set. To be able to control the layout from here, %s your page and set the sidebar to "Inherit".', 'neve' ), sprintf( /* translators: %s is edit label */ '<a target="_blank" href="' . get_edit_post_link( $shop_id ) . '">%s</a>', __( 'edit', 'neve' ) ) ) ); } /** * Sanitize the sidebar layout value * * @param string $value value from the control. * * @return string */ public function sanitize_sidebar_layout( $value ) { $allowed_values = array( 'left', 'right', 'full-width', 'off-canvas' ); if ( ! in_array( $value, $allowed_values, true ) ) { return 'right'; } return esc_html( $value ); } /** * Active callback function for site-wide options */ public function sidewide_options_active_callback() { return ! $this->advanced_options_active_callback(); } /** * Active callback function for advanced controls */ public function advanced_options_active_callback() { return get_theme_mod( 'neve_advanced_layout_options', false ); } } upsells.php 0000666 00000135311 15226760542 0006765 0 ustar 00 <?php /** * Customizer upsells controls. * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Core\Theme_Info; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Types\Section; use Neve\Customizer\Types\Control; /** * Class Upsells * * @package Neve\Customizer\Options */ class Upsells extends Base_Customizer { use Theme_Info; /** * Holds the main upsell url * * @var string */ private $upsell_url = ''; /** * Init function * * @return bool|void */ public function init() { if ( $this->has_valid_addons() ) { return; } $this->upsell_url = esc_url_raw( apply_filters( 'neve_upgrade_link_from_child_theme_filter', tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'learnmorebtn' ) ) ); parent::init(); add_action( 'customize_controls_enqueue_scripts', array( $this, 'localize_upsell' ) ); add_filter( 'theme_mod_neve_checkout_page_layout', array( $this, 'override_neve_checkout_page_layout_theme_mod' ), 10, 1 ); } /** * Dismiss the upsell banner for 7 days. * * @return void */ public static function remove_customizer_upsell_notice() { check_ajax_referer( 'neve-upsell-banner-nonce', 'nonce' ); set_transient( 'upsell_dismiss_banner_customizer', true, 7 * DAY_IN_SECONDS ); wp_send_json( [] ); } /** * Overrides neve_checkout_page_layout theme mod as 'standard' if Neve Pro addon is disabled or not activated. * * @param string $value current value. * @return string */ public function override_neve_checkout_page_layout_theme_mod( $value ) { return 'standard'; } /** * Localize upsell script and send strings. */ public function localize_upsell() { wp_localize_script( 'neve-customizer-controls', 'upsellConfig', array( 'button_url' => esc_url_raw( apply_filters( 'neve_upgrade_link_from_child_theme_filter', tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'proheader' ) ) ), 'button_text' => esc_html__( 'Get the PRO version!', 'neve' ), 'text' => esc_html__( 'Extend your header with more components and settings, build sticky/transparent headers or display them conditionally.', 'neve' ), 'screen_reader' => esc_html__( '(opens in a new tab)', 'neve' ), ) ); } /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { $this->wpc->register_section_type( '\Neve\Customizer\Controls\Simple_Upsell_Section' ); $this->wpc->register_section_type( '\Neve\Customizer\Controls\React\Upsell_Banner_Section' ); $this->wpc->register_control_type( '\Neve\Customizer\Controls\React\Upsell_Banner' ); $this->section_upsells(); $this->control_upsells(); $this->checkout_locked_layout(); $this->product_catalog_upsells(); } /** * Locked Checkout Layouts * * @return void */ private function checkout_locked_layout() { $this->add_control( new Control( 'neve_checkout_page_layout', [ 'default' => 'standard', 'sanitize_callback' => [ $this, 'sanitize_checkout_layout' ], ], [ 'section' => 'woocommerce_checkout', 'priority' => 5, 'choices' => [ 'standard' => [ 'name' => esc_html__( 'Standard', 'neve' ), 'image' => 'data:image/png;base64,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', ], 'vertical' => [ 'name' => esc_html__( 'Vertical', 'neve' ), 'image' => 'data:image/png;base64,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', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'woocheckoutvertical' ), ], 'stepped' => [ 'name' => esc_html__( 'Stepped', 'neve' ), 'image' => 'data:image/png;base64,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', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'woocheckoutstepped' ), ], ], ], '\Neve\Customizer\Controls\React\Radio_Image' ) ); } /** * Locked options on Product Catalog * * @return void */ private function product_catalog_upsells() { $this->add_control( new Control( 'neve_product_card_layout_ui_heading', [ 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Layout', 'neve' ), 'section' => 'woocommerce_product_catalog', 'priority' => 200, 'class' => 'card-layout-accordion', 'accordion' => true, 'controls_to_wrap' => 2, 'expanded' => false, ], 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_product_card_layout', [ 'transport' => 'postMessage', 'default' => 'grid', 'sanitize_callback' => function() { return 'grid'; }, ], [ 'label' => esc_html__( 'Layout', 'neve' ), 'section' => 'woocommerce_product_catalog', 'priority' => 210, 'choices' => [ 'grid' => [ 'name' => __( 'Grid', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAAAAACfVToRAAAEtElEQVR42u3cIXPjOhSG4f3/9KOGgoFmhmZlspvUabITsp5LjMyMzgWSHadNE7fJve1G74fSmbTgGUk+OpL7y8hn8gsCvPDCCy+8CF544YUXXngRvPDCCy+8yP/g9c/vbwteeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeP0Ur9dbsk/Ma9/U1U2pX1Py2j9XN6dJyOsOXFW1TcZrew+uqk7Ga3MXrwsD7MG87sN1YQV7SK96+9VqYpOk1/rL5egrXnjhhddP8drjtdxrv6mrqm72eC3y2sWd9/MeryVeU6Nig9cCr9leco/Xda/N5f3NS1Xv8Jp5rS96barqDFjKXi+X+g1h8L0DY/06v36Nc/UtWNLPx6nX+vJxm+wNWNJeYy9/c6mreAqWeH3fPFfVenu5CXsCxn77es96DobXghb/DAyvJSciRzC8Fh0gTWB47ep6e/28bQRL3mtXz8v7j48n6z1exxbY9vpp7itex45hALt4+I3XjKuqttfuCuA156qq7ZWrFXj9bj5zZQIvvPDCCy+8EvHarj+RHV7cz8ELL7zwwguv+fsK66+mTsyr5v2OT3nd6f2hXSpeu7twrdN5/7G5A1e9S+h95OY/5XrA9913m5sW/efL1/Ufz4v/p4AXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXkl6dX++LX+l1yMGL7zwwgsvvAheeOGFF1543T9OMfnh+pe9lOM1przdq1zyVx7FSx6vJV65mVmTSSu8FnuZlzSY937ocpVmvZck34evNSvJNee9vJNUHhLzaiT1JqmRVFo7TtLRQZIyKTeT1JpZL6k36920/MVvKaHxFVBU9mE585K6YHkIau+8nFSYHTKpSckrrl+SVA5mRZxYpVSYufgsyN97NZIzM3uSigSfj4p8WZyIraShD6NsXO9PvArpKdF6ojQzSc1xrsUP7TjHmvdeLvxCel6hvj9dm/D6eL0PiRan83E4Ox87Sb3lcT723vuEvWbrfW62iuv9avTyUwHi43rv01nvz3l17+oJP9UTK8n11jlJvQ2xngi/WP6IDfk3eNnhXL0axlcTfghewW18XPh06tU3Xmf3Q733jZkdVpL8MD4Twn6onareh/Z6xOCFF1544YUXwQsvvPDC6+b4HC+8bkyzmvUhfCa5cC+gfZo3KPCKyWP7qrXj2avrx1bW2ADDK+ZpOh7qzVbjZ3fsF8YmF15mFg55ijCYnsa2cyHpUEiu83nvfkRH/sd4jccVhVRMhxyZ5J3kzefmpQyvKWU8DiulwlxcrJzkV9GL5+NJDt63I5F57/s4RzsvqcgdXh8NMzfEz8NKKqYHQeYHvN6ky0MJEUbceGLUxYoia/F6u+ariKNoKOb3WL3zkrIer1lFsZLcWJO2mZR38/3Q4BbcA07Iq8uOg2sswCzcBxjM52Y5XrMM2awebXW8nJTFeqLP8Dq7HZI7boekMtYTrF+nyWZeneZ3DfPpM8/HY2ZErj3xsiY0K8q/r6FDvxCvh/T6S4MXXnjhhRdeBC+88MILL7wIXnjhhdcj51987R/KzzMKWAAAAABJRU5ErkJggg==', ], 'list' => [ 'name' => __( 'List', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAAAAACfVToRAAAE0UlEQVR42u3csVPqTBTG4fv/t2+bckvKdCnT2W2iGASH5ma+JlW6VOcrdkOCIKBBwJvfW+GMOvLM7ubsctY/Rr6SPxDghRdeeOFF8MILL7zwwovghRdeeOFF8MILL7zwwovghRdeeOGFF8ELL7zwwovghRdeeOGFF8ELL7zwwovg9RNe/73fLXjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjh9Sheb1OymZnXpiqLSSnf5uS1eS4mp5qR1xW4imL1bS+nmHR7/n16Kb2z1+oaXEU53UvKp3vll/yWSV7Lq3idGGCXe8n/Aq/rcJ1Ywc57pWZmVSItfo1XufpuNbG8kpd5SZ1577smVW7Weknybfi2aiG56riXd5Ly7S29Xr5djr5dy6uS1JqkSlJudT9JewdJSqTUTFJtZq2k1qx1u+Uvfpdm4RXGV0BR3oblzEtqguU2qB14OSkz2yZSNSevuH5JUt6ZZXFi5VJm5uKzID30qiRnZvYkZTOZj+PnoyJfEidiLalrwyjr1/s9r0x6uv16P/La3M0rNzNJ1TDX4ou6n2PVoZcLP3Anr82yLIqy2tzBK9T3+2vTo3ut4877eXNLr3GJEC3252N3dD42klpL43xsvfc399odVCzv7TVa71OzRVzvF72X3xUgPq73/g7r/WgvubmzV3NQT/hdPbGQXGuNk9RaF+uJ8IP5ZRvyK3ktT+9vXotyfSsv2x6rV8P4qsIXwSu49Y8Lf9P66+Wk17IojoD9lNfR/VDrfWVm24Uk3/XPhLAfqndV7828Xk+dN4TBdwA21esuucH61c/Vj2Bz9hrOWl8/4zoAm7VXf5a//JzrI9isvd431XNRvKxOcX0Am7fX8Xw8sx6D4XWWaw8Mr/NcYzC8LuAageG1LsvVOa4BbPZe63Jc3n/+8WS5wet9dwS2OsdVFG94DSeGAezkh994jbiKYnWuVwCvMVdRrM60VuD1Xn2lZQIvvPDCCy+8ZuK1evlC1nh9I3jhhddMvHyKF14TvarFqE/CJ5IL9xbqp3EDxWN5FS/fTTnVK43tNbUNveGu7Vtt+gadh/GaeJdv8v2Op137amu26F+7oZ8pNuE8iteV7g+tv+nVSsrCYHrq2+IySdtMco1PW3dZx+DNvNZX4Tqx/p1Z0WM7ZSZluybMRPJO8uZT81LySF5f2zOe+XDt6155bNfNpcxcXKyc5BfR69Gej9cAO8V1xmvrfd0Tmfe+jXO08ZKy1D2g1/t6OWnRfz7drn/RG8gl18XX3ULKdg+CxHeP5vWzueDPb9JQQoQR13e0NrGiSGq8Pq75yuIo6rLxPVvvvKSkxWtUUSwkt41f1ImUNoNkap274J7yjLyaZBhcfQFm4b5CZz41S/EapUtG9Wit4fJUEuuJNsFrlGE7JDdsh6Q81hOsX/tJRl6Nxnch091rno9DRkSu3vOyKhxW5D9woPOv/j+rh9wP4fXPeP1U8MILL7zwwgsvvPDCCy+88MILL7zwwgsvvPDCCy+88MILrwlezd+75Vd6EbzwwgsvvPAieOGFF154EbzwwgsvvPAieOGFF1544UXwwgsvvPAieOGFF1544UXwwgsvvPAieOGFF1544UXwmpz/AdpnH8pqwZaBAAAAAElFTkSuQmCC', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'woocardlistlayout' ), ], ], ], '\Neve\Customizer\Controls\React\Radio_Image' ) ); $this->add_control( new Control( 'neve_add_to_cart_display', [ 'default' => 'none', 'sanitize_callback' => function() { return 'none'; }, ], [ 'label' => esc_html__( 'Button Style', 'neve' ), 'section' => 'woocommerce_product_catalog', 'priority' => 230, 'choices' => [ 'none' => [ 'name' => __( 'None', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAAAAACfVToRAAAHHUlEQVR42u3cPZujLBQG4P3/ra2lpaVdSjs78jWOH5eVnc1rZ+WbRFRAiCTuxgAP1cxJZNZ7EQ8I/um1yn/lS+XIlMscvh4lpdCpsDjfvvmj8cULW3X5clmF+PNJr7PMK9PlOh6v8NLyKsYDr/DS8Crm465OeV3e6r8Klvnqklcq4Tq9xLUKZpVXIfG6vsa1doBVXrILMn+RawXMLq/iJJ78z8tcz8Hs8ip/hVO/vMH1FMwyLwHsUrzD9QzMNq8yZwzS8j2uJ2DWeZVldn30Yue0eJtLDWah18NifZT9lEsJZqlXuZVLBeaq1yqXAsxRLw0uOZibXlpcUjAnvTS5ZGAuemlzScDs9SqyrNjKtQSz1iu7Ja2nfCvXAsxWr2yYLMy3colglnpl4+xqvpVLmBKy0yubp6PzrVz8H7DSK2Pn7/ONXPZ7ZfwDj3wbl/VemfiEKN/EZbtXtnyklm/hstwrkz2DzDdw2e2VSU/5BvY2l9VemeKcT9nbXFZ7XY5/v8ALXvCCF7zgBS94wQte8IIXvOzz+rn8/eLA845/V+AFL3jBC17wghe84AUveMHre7xOxQe5+A2WRnodT5fPFX4/qpleu5WTMV6nr/A6G+N1/QqvqzFev1/hlRnjVZzM7L728pK+yeTTJTXIqzyb2Nvv6JXvfUW+lybv5rU32CkvzfLiXjTx+YvxzUHYjl63Tn+vJnZKy9JAr7L4vX6e7Hz9fX+Ev6+XeQVe8IIXvOAFL3jBC17wghe84AUveH2vFwq84AUveMELXijwghe84AUveKHAC17wghe8UOAFL3jByy0vTyghqbf/7XaoywWvW4kaeL3i5Xnpvl67aG/x8ip4veTlt/B69m+L6G91TMESeOl43cRoA4OXnldPW1gDLz2vStbjk9DzYvpzc//F8wIi3hSq5B6Pq1e8pJUZ5dXOKcXQ1Nq+CR4QwwlG810hYE+ynT4IW8Yr5hMUj1bZLysbvhNx9x1iohft0h5eKX8fjeeG4jOnXut5CZUdjPRirsfhXEeJuw0RE4/DqOyz0UDLK5VVZpwX098PP0ZzW2qWmRo9o0iWxT33aqTjCtO82HwiFq892m4ON8wu8Zhzr8e0rbs5HPS8IqYy2m4Ds/PVyStu2AuI/qc3TBd24JKQRMerllXWGD0eGr3GGZ4D3xbJ1BI74erR6b+GysKeqzs1erwdCww+p9d3/tgmhnuE342fpBpevnpgb5xXynb9E0Mjnkc0chKhE9TIv2hlnQVe03xhzKUMtBWF87HJ2NXF4hh93WtRmaFe7Hx0zF+OqZh6kLHDj8Wbf7DqtajM1PFQ38Nrk1e6fj0ma9cjUXiFNnut9ffzyTcqr27yqoXKGnIvtU1enSfNJ6rp5Fv+QmW8Eh6yXVaWLPKvznQv2p7EfLWbkqlYma+GPGS7qIzat5JJH3O9Ui47a/zFeChdjocI247GWYx2UVnCsvJTH+Z6je0mZobI/Hg7bsXxNp0e8u+1EJ89Jlgekoo5DjHbq1omtwk7/JPM53SyD1p5ZSE37rLAazlfGEnnCz1/vsNxk0J+xHRNRPXQk1jjJZ7jQTof7ZE5X+Ulq5jtyvnKgka4sdjgpfO843YE40WfljwaUN1zXn0dMtORbP5QJd/q9XpRPk+ryTAAvZ34I/mcB1IPpej+e/X4oGOOCYbPPpw9fNDL0gIveMELXvCCFwq84AUveMELXijwghe84AUvFHh9o1fKLH2AF7zgBa/9vAhd1ZZqxTsaXj6BdMOLeSzvV6vxll1a4qfOeXWhfEWEIl4pFpy44iWwTDCK+HIRUuSWV6LY3CGPC8uWPr0mZH+vdl5pM+7QeyxIVcTjcdve/f5YB8K2IQe8BougZS+2Sh33xxb1yCda36IGpuflc0u8omkFrzzeTDv4hvwr2WNh7p5eDf9yjmmfmSJeT7tgB69nm6as9KpkO9ACZbwS2pdz+X3Kb/yZNvUo4o3H9V+uehG+9z+o4zSdOFQYb8/ZFVHH2cXhceW6V6jYuDPHu4DP+YnDXl0kvuNFEm8CO7P7171GCfHVckK8i8VNLK2TXtPkTb0Wbwk/iAxa97yaUM6liLfkYN0MxSte05uSwkYr/viETO2sdszrsHyd19P4lN8Tz54BpLZXG0yvOdOKM16Lje4OeE0b8eL1uM/uJr571exrqJzwmmZMK414OL10ino1Br4oeptXuNis+SSeTCkq9Upda19EkUPJ49WUuQ5edHjkTn9PX/uweDutKu6P+2QfXnQC36F8gnjyff1r8eiWasQO5qsHhYsq3ofLqEvjIV/hooovH+Mu7xQWe3Xytxcq4/cizE/Edjx91PNqFS7tE6++YTq3xJLG1f/j9V/3+YnYosnVHuvl4AUvd7zsK/CCF7zgBS94ocALXvCCF7zghQIveMELXvBCgRe8PlH+B8qWKH6NIXX+AAAAAElFTkSuQmCC', ], 'after' => [ 'name' => __( 'Bottom', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAMAAACN4JX/AAAAq1BMVEU/xPtExftRyvtSyvtTyPtbzfxhzvxkzPxm0Pxv0/x00fyD1fyM3P2R2fyTk5OcnJye3f2kpKSn5P2q4f2srKyy5/2z6P20tLS25f27u7vB6f3Dw8PH7v7KysrK7/7M7P7R0dHS0tLT09PU1NTW1tbW8v7X8P7Y2NjZ2dna2trb29vb9P7c3Nzd3d3f39/i9P7l5eXs7Ozs+P7x8fHy8vL1+//5+fn+//////+ynh90AAAHOUlEQVR4AezQwQ1CMQxEQVrB/lJC5D1xof/KKAFyAGelNyXM7fWNp7bM+wke2vZ54idfFQd0hWy+NA74GkZfyvaulNPXiuauqN4vs7BY8vrSysauLLl9SSOatmJIhl+qef2/LK9Z6v/yxxdffPHFF1988cUXX9744osvvvgCX3zxxRdffIEvvvjiiy++wBdffPHFF/jiiy++3uzb0YrzKhAH8DcYEQIhSGDuvBMF8fj+T3ZIM50aE9d87MWSOv+r7XQzkB8q2qZjeUGVCX3+dSK88u1elDnkexEviv1bL7r6OV7g8r9EvFTMP0S8ZnrlDYGtuRPxIjEaYLkT8aLQCAv5VsTLXa34OAGYvCdsLwA0unyMW7e6cfe86mZP9aJ7tTzUYg4a4O0VZuDo8iYjvzHFwstQNwpQy3xutv8PVSj4RC8PwF4WKFyjBAUc7e95Vc2WJ3rxfOR7Depjg1BleSursqpvedlzs+d58XrPf87AXgGq8B3NVbnrddnMPsur3k+Yeu5pGgch57RSORZXwZpyDss9r7lohjQun71fNUwVygmEtGIVS9hy2ISsd7z8VbPw5PMQe/m8ZyFbCvJITNXs0X0vajblQ2/76PO2qRgU6VGSeo8Jt8ulTLF9L2rmvuK8Tbdnjgyhvo/5zYnVIhj7XtQsfYHXHHLptRx3GlPmrO+lztAfnK4XN3u0V/V5tDlOR1uNIhpWpvxHiu56UbNHnx8pv/ISL9ufj2tvPmLDa/pWr856X918aHkl9vJVs4Bb/Dd5JbjcTzi++ZgpWHutR8h4brae9l/p6V55vtyvJt5MmeZ+dTpCxqoZ28dy0j7ey0JZCOp0HrLn8xCW4ygqpqiarSUrHSyf7sXjxvARuT5vm1iftx0dsOxmp8prdHHJ0Rs4+GwvB6esfPw7hxe9OvGyGc9a9XwvCkKVufq8kLK/oiZlfS6WJmx96YnP92qALdXn0RTU5FVLOsNep2Y6cLP5a7x633fQFYVXDhooyueDV/YTcEyqv2r6Y6/fp/N9msf9AJpyxlcyxb6UZtwgcEsqrtH7e1Gel/ttxEu8xEu8JOIlXuIlXuIlES/xEi/xEi/xkoiXeImXeFkAn/884iVe4iVeSE+12Vv1RGWNbkgvBI5y3XpcoKjb4bzSBGWWTt3BMfNYXhULwbTrDurMY3mtUMf+UI8KTsGRvOLnSZtERCq16wZeWZMF8F5TfSCv3ULH6qe1rbqCLUj7iUgvx/EiAHt4Ts0064F+wUdepLqM40UAxx3E3Kx72KLZi37xMY6Xu/oFmm7WHTEOu7+3sGU9vpya9QCv4OBeeFz9l3Zd0V7MyXn7s7vCdt3AJ8aN7kVb+tiuJw1lFhzYK800bn6qBw3H4KBeLKHij/Vk4JgpDumFQPG9ekQFZXQczytMzHKnHnGBT+bhvCxQptCt8zvI48wP5rUAxdyqk5fnyboM5RU1qWjfrVdeBDaN5BUUsZh+fS9F9uID+Dhe8c3i+nXauAb2eh8ox/EiAtDhTn2lLSp72dHGFxJLvFV3750reSU92HqfaNaFm/W9rPzu5fVo+wmEq/Tr8wJgBtyvLnCVdp2WtWHPQwqu0q7ndALTIQ/jleAyzfoWc6yZlMfxinCZZv2VgMBZgzz/dSe4ABjMfxZ5Xk68xEu8JOIlXuIlXuIlXhLxEi/xEi/xkoiXeImXeImXeEnES7zES7zES7wk4iVeD/D67/927GBVahgK43jVaLS1UAxKKGJXduOiEAj83//JvHMzJ7VJYeCqlOj5Nu3JDGXyY05I+u1zQ/ny/Wqvj11b+XSx16vGvN5f7NU1lnfqpV7qpV7qpV7qpV7qpV7qpV7qpV7/r5dxEXD2OOo2wPf/ptcCMd1NpARnylLCnvWpHKUYuz19IGUSPiDhWSTeVg9rw8vs052QxL4uT7x6qMFsKAc3wBdeBNOmlwNYCi+ircoTrwDhyWTYnqd/zwy4++CtTqoxez1fN/Btem0QIDVg+t3GA3NV5qzSaZNAmihDiWRMg/cu9BDuY+LVOSGSh7Xi1cPqwYmXzCZWZe21gMt/0qXLt1u6G50bbtdInGAtvZYmvWZwPYSDlwH6sqy9AgxZXURnWask040mgi36cWjRy0QwMnEBShJlWXuRELJDBSAD403RHdf7qWvPS4g8zH/Ly0I03Qjh6OWa9FrBpXYyRT/aonxhP8pKFWHYXQfAtuZV9ccfXu9TDwYks3jJZ+15OXLWHcgDviof7Cfc+X5iICea3cuBb85LuiQ34GFuZVl7mbxf/fUbC6nHt2fuRSQ3mHavEebmvGQVltZ6fB4qpjienocikl6WPtmhZq+hvf2XrPbSWsEIUJTz9qGsvR6dt8ektPdpn70MRNOc1+/HOs7e5wTAW33/9fKol3qpl3qpl3qpl3qpl3qpl3qpl3qpl3q9aczrw8VeX183xfX2x6VemgdeGvVSL/VSL/XS/ASH6S8TuuP7JQAAAABJRU5ErkJggg==', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'wooaddtocartafter' ), ], 'on_image' => [ 'name' => __( 'Overlay', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAMAAACN4JX/AAAAtFBMVEU/xPtDxfpOxvhTyPtWyPdbyPZfyfVkzPxnyvN00fx+zu+D1fyR2fyTk5OV0uuXzOKZzuScnJyc0eee0+me3f2kpKSq4f2srKyv1uay1uW0tLS25f27u7u72OO/2OPB6f3Dw8PKysrM7P7R0dHS0tLT09PU1NTV1dXW1tbX19fX8P7Y2NjZ2dna2trb29vc3Nzc3d3d3d3f39/i9P7l5eXs7Ozs+P7x8fHy8vL1+//5+fn///+lQ2ZqAAAHR0lEQVR4AezQsUrGMBiF4Yro4GB/7OTgdr6mpU0+Mzl4//flJAR+oR0kyaHnXd/tGb7P9JWv0bGEvORF7OUp1i05r1daDfWzNVF6eUCrgvN5RUO7LLJ57WjbzuUV0brI5OWG1pkTeS1o38rj5eghp/Ha0EM7jVdADy00XoYemmm80EXG6TVv9ZpRRulluWJu9F4h1yzI66/kJS95yUte8pKXvDyfTV5xmQFY2E6gySsF/GZbPkheEWXhel6f79N9Y9FtKnobi4r5b93Goum+j9ZeLwNXr429Hgaunht7DWQ9yUte8pKXvOQlL3nJS17ykpe85HVVr8cfdsyeVXYQDMIXLCTEMthYBFKmDQgvz///X3fPccdsNLBwPwoPO407Jgg+cd5VowHRX3vjAaTpZ/LawMqvhaIcXWslTu0PG2TCy4BTpmgRPqDA80jJN4ONwsud012QbGrtLa8JemA+t50HkBpeZDcmrwiwNbww39hbXhnyg8l8QHYacAXis7OsNwCrvL7bA9KYvA7IoADuj8YlYO1s1a6kLQLpTF0FSXh2lhQmyBD0UF9pvww2Cq8J9gRRvDQb62zPa4NYF+l2rtej/Aoxzl+tYRrqldc2JK8V4gT5wssBU2t7XhnmSt00oGqVtHyhMfBNHucReTkDVyYuXiLR2p4XBULl0AFQR/j+LJd6r5eG4iVECdb/xcuDuV8B8pVXHJLXDrHEyTV59I39wzyqUhnMJ9cZ8OPxavLxj+t9yWBGWsVLz8bjFanaT0AJSK19t5+I9/uJmSpzl//HNBwvpaQG8DK31va8XN2vvr6xUTJ+wP6yBg9YTl4B1uF4qQorWu/PQ80Uw+15yJAmlT7tUCuvebz9l6q9opWdANnlvC3b8Xp73g6F0pnTqfJyYG44Xn8vH7m7z8nPG4jP/dfnvvA3e3dsqzAMRmFUenoFI1BRxXaihFjsvxwlfYhiXXS+EU7hzv89Hi9evHjx4sWLFy9evHjx4sXrL8zrNtjrngX2/4j6L9qm82s//L92aee3hHu5p8CLFy9evHjx4sWLFy9eB3YO3PedSruuMuV7uU/u/v3JXrN9hZixpk/PGK9eop6vC7wCBmLWIK9XTXztB3rtJXEObJzXaLCyp+0/7nUgV+2Be6xrGaRV1sz92r7N15PVeev2pL+MFy9evPLjxYsXL168ePHixYuXePHixYsXL/HixYsXL17ixYsXL17v9s1g1XUQCMNPMAsXEpAsDLN0Jwqi7/9el5xOp2qaYy5dHFLnWzV/mwE/VMa2EcSX+JrLl/gSX9CxYCgfk+CHb/dFmFiuIb4I97e+6O77+AJf/gfxpVL5BfFl6CpYEraVAeKLjNEEKwPEF0EzLJZLiC//bsfHBcDS67hfAGj0pcVve279RV9dsbv6orE6nmqpRA3w9BUNMLoeZOI3llT5slSNACpZjsUen6GEwDv6CgDsywHBGREVMDpc8tUXW+/oi9cjjzWqlxuEjvVpWUGFvuTLHYvdzxfv9/zSAPuK0MEjMtAz9PWmmLuZr66fsP3a0zQPYil5ozhVd8GWS4nrNV+mKoY0L+/dr7IvG+sFhLRjVVvY2jQh2xVf4V2xeOfzEPsK5cFKbgnkmZi71aPHvqjYUpra7tbnbdtpUGSPyOo5J/zDXC6EG/uiYv4rzts0PNtqiP04zFMndptgGvuiYvkLfJlYal9r22kshdmeW52lF8zYFxe7sa/++2jbLkfXzSKaVrb+IKGHvqjYzc+PhPj6wJcbr8dttB7xxNfyrb4G+303+HjmK7Ov0BWLuBO+yVeGt/2E58GnQmDva2tFpmOx7dB/5bv7KuZtv5q5mbKn/erSikxdMXaf6kV7e18O6iCqw3nIHc9DWM+jpFhFV2yrtdLB8u6+eN5YPiL3522b+vO2pwPWXgVVfY+ubml9A4P39uXhwMbHvyO86fWkY7F61apv8VUQOkz3fSHxuKIidW6qrQnPfvTEm/s6F7Z230cTqMlXb9Jb9nUopiMXM1/ia/x7B91R+SpRA6FCaXyVsABjc/9T09/7+ozR72kBHwfQXAr+UAj3Y8ngLgJ3cnWPfryX5P9ynyK+xJf4El+C+BJf4kt8iS9BfIkv8SW+xJf4EsSX+BJf4ssBhPLniC/xJb7EF9K/2tylPFOs0U/pC4FRfpinFarcTecrL1CzDnIPLWYyX6SlF3OWe+gxc/naoMf9kicFB3AmX+n1T5tMilQ+z+3zsT0HEIKmfCJfDxc69Y/WnuQKdpD6iUSX8/giAa75n5o9zSM9wUe+yOo6jy8S0HYQ5jQPsKPJFz/xMY8v/+4JNH2ae9I4bX/vYGdrL5fTPMIPOLkvbHf/9TxX1It5OW+/uis8zy28sH52X9TSp/M8a6hZcWJf2dC8+S2PGlpwUl9sQqVf82yhZUlT+kIgwihPqKBGp/l8xaXWMswTrvDCTOfLAbHEYc7vIM+zMJmvFQh7Lef+HuGLDpD/AAHTXdCQ3yy+AAAAAElFTkSuQmCC', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'wooaddtocartonimage' ), ], ], ], '\Neve\Customizer\Controls\React\Radio_Image' ) ); $this->add_control( new Control( 'neve_category_card_layout_ui_heading', [ 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Category', 'neve' ), 'section' => 'woocommerce_product_catalog', 'priority' => 300, 'class' => 'category-layout-accordion', 'accordion' => true, 'controls_to_wrap' => 1, 'expanded' => false, ], 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_category_card_layout', [ 'default' => 'default', 'sanitize_callback' => function() { return 'default'; }, ], [ 'label' => esc_html__( 'Layout', 'neve' ), 'section' => 'woocommerce_product_catalog', 'priority' => 310, 'choices' => [ 'default' => [ 'name' => 'Simple', 'url' => 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA5MCA2MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjkwIiBoZWlnaHQ9IjYwIiByeD0iMSIgZmlsbD0iI0YzRjRGNSIvPgo8cmVjdCB3aWR0aD0iNzEuNzUiIGhlaWdodD0iNDEuODM3OSIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIDEgODAgMCkiIGZpbGw9IiNEREREREQiLz4KPHBhdGggZD0iTTIzLjU2NjQgNTBINTEuMTk2NCIgc3Ryb2tlPSIjQzRDNEM0IiBzdHJva2Utd2lkdGg9IjIiLz4KPHBhdGggZD0iTTU1LjMxNjQgNTBINjQuNjg1NSIgc3Ryb2tlPSIjQzRDNEM0IiBzdHJva2Utd2lkdGg9IjIiLz4KPC9zdmc+Cg==', ], 'style-3' => [ 'name' => 'Boxed', 'url' => 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTEiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA5MSA2MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3QgeD0iMC4xODU1NDciIHdpZHRoPSI5MCIgaGVpZ2h0PSI2MCIgcng9IjEiIGZpbGw9IiNGM0Y0RjUiLz4KPHJlY3Qgd2lkdGg9IjcxLjc1IiBoZWlnaHQ9IjUwIiB0cmFuc2Zvcm09Im1hdHJpeCgtMSAwIDAgMSA4MC4xODU1IDApIiBmaWxsPSIjREREREREIi8+CjxyZWN0IHg9IjI1LjY4NTUiIHk9IjEzLjgzNzkiIHdpZHRoPSIzOSIgaGVpZ2h0PSIyMS4xNjIxIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzAuMzE0NSAyNEw0OS4zMDk0IDI0LjI2NDIiIHN0cm9rZT0iIzk5OTk5OSIgc3Ryb2tlLXdpZHRoPSIyIi8+CjxwYXRoIGQ9Ik01Mi4wNjA1IDI0LjMxODRMNTguOTM2NSAyNC40MTkiIHN0cm9rZT0iIzk5OTk5OSIgc3Ryb2tlLXdpZHRoPSIyIi8+Cjwvc3ZnPgo=', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'woocategorycardboxed' ), ], 'style-2' => [ 'name' => 'Hover', 'url' => 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOTEiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA5MSA2MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3QgeD0iMC44NjkxNDEiIHdpZHRoPSI5MCIgaGVpZ2h0PSI2MCIgcng9IjEiIGZpbGw9IiNGM0Y0RjUiLz4KPHJlY3Qgd2lkdGg9IjcxLjc1IiBoZWlnaHQ9IjUwIiB0cmFuc2Zvcm09Im1hdHJpeCgtMSAwIDAgMSA4MC44NjkxIDApIiBmaWxsPSIjOTk5OTk5Ii8+CjxwYXRoIGQ9Ik0yNC4xODE2IDI0SDUxLjgwNjYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIvPgo8cGF0aCBkPSJNNTUuODA2NiAyNEw2NS44MDY2IDI0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz4KPC9zdmc+Cg==', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'woocategorycardhover' ), ], ], ], '\Neve\Customizer\Controls\React\Radio_Image' ) ); $this->add_control( new Control( 'neve_sale_tag_ui_heading', [ 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Tags', 'neve' ), 'section' => 'woocommerce_product_catalog', 'priority' => 600, 'class' => 'sale-tag-accordion', 'accordion' => true, 'controls_to_wrap' => 1, 'expanded' => false, ], 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_sale_tag_position', [ 'default' => 'inside', 'sanitize_callback' => function() { return 'inside'; }, ], [ 'label' => esc_html__( 'Style', 'neve' ), 'section' => 'woocommerce_product_catalog', 'priority' => 610, 'documentation' => [ 'link' => 'https://docs.themeisle.com/article/1058-woocommerce-booster-documentation#sale-tag', ], 'choices' => [ 'inside' => [ 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAMAAACN4JX/AAAAVFBMVEU/xPtTyPtkzPx00fyD1fyR2fye3f2q4f225f3B6f3M7P7S0tLT09PU1NTV1dXW1tbX19fX8P7Y2NjZ2dna2trb29vc3Nzd3d3i9P7s+P71+/////8xOQAQAAADLElEQVR4AezQMQ0AMAwDsLDYMf48i6Gq8tkQnL+BL1++fPnyhS9fvnz58oUvX758+cKXL1++fPnCly9fvnz5ov3lC1++fPnKwWvx5cuXL1++fPny5cuXL1++fPny5cuXL1++fPnyNezXsW7EIAyAYRPiM8eWjfh///dsiNOrVJW1k/8BmfUTIPEPXsUc3GJTwe/h5JTo5GlPr8n1eIwydw3Q9GLt1UDv1SaeA/2XV0xRevW4gM77Wl/QoKTX2stgWL2GqXTQC1h6rb3kYNb1GjdQ6Yw/368jvaLdHMBEDBdRqOm19IrMoXxoWt7HlVeBdoPBtvPk6bU8Xwe8ROrA5R0yCppeK6/qRPp91MTpP6/WZ5qsUf6HoFUx2GXWYftqx25zrIZhMAovIElTtfnY/05B/LhKecHcMEMYxefsoI/qSPb/8mLfxuv42/LVPHqFD5QbXlPFgtdcBa+pYsNrqozXXA2vqW68pjrxmiqzD73R+fI68HqjhhdeeOGFF1544YUXXu/Wf5l+UW8xvEp/NMEryeJnhNcdHlWbBK8klwUjvFp4Fk2QI8Tbt1cNP2VxpfC9C68xm0vBmEebS8FcefX49DosLgFz6HU+vW6DS8A8erU4QiSDS8BcevUyMMRqcAmYT69+xwkuAfPn1Vv+IRbPZnEJmDevsVpK7d3mEjDHXppyKRheE1wChpfJJWB42VwChpdyCZhbr5LSNcElYM68ilxXDS4Bc+AlXAOYxSVVH17CNYJNcIXiw0u4RjDhwku4RjDhwku4BjDhwku4BjCDC6+iAvn3XHjlGRu88MILL7zwwgsvvPBa7HXnD1a538+HF1544YUXXnjhZYdXbJ/vVTb2CvH49MKrvItXDEs6d/FKa7yuXbzONV51F6+2hOvoG3gt/MHqPl49rXi9NvJqaQHXBl6rRjKWvplXb2eK/wjruHvfwGthG3jhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOFFX9YLL7wIL7zwwgsvvAgvvPDCCy+8CC+88MILL8ILL7zwwgsvwgsvvPDCi74BKevIZRVAXf8AAAAASUVORK5CYII=', ], 'outside' => [ 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAMAAACN4JX/AAAAVFBMVEU/xPtTyPtkzPx00fyD1fyR2fye3f2q4f225f3B6f3M7P7S0tLT09PU1NTV1dXW1tbX19fX8P7Y2NjZ2dna2trb29vc3Nzd3d3i9P7s+P71+/////8xOQAQAAADR0lEQVR4AezXMWvDMBBA4XNsRY62THX0/v//bA8lKQQ0lIZ2eW8w5/XDZ7jAfpJeeumll156mV566fWW9NJLL71ML7300kuv+EV6PdJLL7300ksvvfTSSy+99NJLL7300ksvvT7+ML30eld66aXXUjv0Ol5W6JHduMXoxr1Nr+S6exxLfLUDRa+5VwqVfFITrwPtxWtMI73aWMDOJSLOsMOi19yrwlHXiEilK22BqtfUK42yViLiBCUax4vX6KrXaKsdoEZUekSBVa+p1yjJlifNPttHvZbUSTA4bdzres284grniPWgx2XIFCh6zbzWzqg8PrXotO+/1nNK1pH3EOxrVNgia3DS67/vbb300ksvvfTSSy+99NJLL7300ksvvfTSSy+9Ptu511y3QSiKwgPggWXzmP9MW/UPanfvaaISdHVYawif4sTaKOSFlbu79wprKx2vt4p1v9eCxhdd4eNVR15P+Hyxu/HqMWyouPG6w5a6F6+8x+vx4hX3eF1evMKeij+vNpalryrZnVce6+t44YUXXnjhhde5XrWkGNPVXkHBq2frtXyGl0w8Ca9/eqWXliu8/j64Nrxsr2QsCxJePfxeNEFyiM/ZXi38kcWVws9uwwsv4TLAeB6FS8AO85JFP1tcAnaal553PwaXgJ3mpSe4yeASsCO9Rg2z2AwuATvTazzxFS4BO9Zr9PJLLF7d5lKwY/fCVmuzfxltMPZVm0vB8LK5BAwvm0vA8LK5BAwv5RKwY71qSrfBZYAd6VV1XbW5FMy3l3BNMJNLakd4CdcEs7mkeo6XcE0w5cJLuCaYcuElXBNMuPASrglmcOFVVaB8zYVXeRlmvxdeeOGFF1544YUXXng95T9rq734fwdeeOGFF1544YUXXrGv96qOvULMy3N4Hwz3Db3nlfZ43V68rj1ezYtX38KVhxevPR+w5sdrpJ3fXg68etrF5cBrwyMZ63DmNfqV4oew8jOGK6/94YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjh5cCL8MILL7zwwovwwgsvvPDCi/DCCy+88CK88MILL7zwIrzwwgsvvPAivPD6Lv0ALgqZQ3JkuCMAAAAASUVORK5CYII=', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'woosaletagoutside' ), ], ], ], '\Neve\Customizer\Controls\React\Radio_Image' ) ); $this->add_control( new Control( 'neve_card_content_ui_heading', [ 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Content', 'neve' ), 'section' => 'woocommerce_product_catalog', 'priority' => 500, 'class' => 'card-content-accordion', 'accordion' => true, 'controls_to_wrap' => 1, 'expanded' => false, ], 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_product_content_alignment', [ 'default' => 'left', 'sanitize_callback' => function() { return 'left'; }, ], [ 'label' => esc_html__( 'Alignment', 'neve' ), 'section' => 'woocommerce_product_catalog', 'priority' => 520, 'choices' => [ 'left' => [ 'name' => __( 'Left', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAAAAACfVToRAAAEtElEQVR42u3cIXPjOhSG4f3/9KOGgoFmhmZlspvUabITsp5LjMyMzgWSHadNE7fJve1G74fSmbTgGUk+OpL7y8hn8gsCvPDCCy+8CF544YUXXngRvPDCCy+8yP/g9c/vbwteeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeP0Ur9dbsk/Ma9/U1U2pX1Py2j9XN6dJyOsOXFW1TcZrew+uqk7Ga3MXrwsD7MG87sN1YQV7SK96+9VqYpOk1/rL5egrXnjhhddP8drjtdxrv6mrqm72eC3y2sWd9/MeryVeU6Nig9cCr9leco/Xda/N5f3NS1Xv8Jp5rS96barqDFjKXi+X+g1h8L0DY/06v36Nc/UtWNLPx6nX+vJxm+wNWNJeYy9/c6mreAqWeH3fPFfVenu5CXsCxn77es96DobXghb/DAyvJSciRzC8Fh0gTWB47ep6e/28bQRL3mtXz8v7j48n6z1exxbY9vpp7itex45hALt4+I3XjKuqttfuCuA156qq7ZWrFXj9bj5zZQIvvPDCCy+8EvHarj+RHV7cz8ELL7zwwguv+fsK66+mTsyr5v2OT3nd6f2hXSpeu7twrdN5/7G5A1e9S+h95OY/5XrA9913m5sW/efL1/Ufz4v/p4AXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXkl6dX++LX+l1yMGL7zwwgsvvAheeOGFF1543T9OMfnh+pe9lOM1przdq1zyVx7FSx6vJV65mVmTSSu8FnuZlzSY937ocpVmvZck34evNSvJNee9vJNUHhLzaiT1JqmRVFo7TtLRQZIyKTeT1JpZL6k36920/MVvKaHxFVBU9mE585K6YHkIau+8nFSYHTKpSckrrl+SVA5mRZxYpVSYufgsyN97NZIzM3uSigSfj4p8WZyIraShD6NsXO9PvArpKdF6ojQzSc1xrsUP7TjHmvdeLvxCel6hvj9dm/D6eL0PiRan83E4Ox87Sb3lcT723vuEvWbrfW62iuv9avTyUwHi43rv01nvz3l17+oJP9UTK8n11jlJvQ2xngi/WP6IDfk3eNnhXL0axlcTfghewW18XPh06tU3Xmf3Q733jZkdVpL8MD4Twn6onareh/Z6xOCFF1544YUXwQsvvPDC6+b4HC+8bkyzmvUhfCa5cC+gfZo3KPCKyWP7qrXj2avrx1bW2ADDK+ZpOh7qzVbjZ3fsF8YmF15mFg55ijCYnsa2cyHpUEiu83nvfkRH/sd4jccVhVRMhxyZ5J3kzefmpQyvKWU8DiulwlxcrJzkV9GL5+NJDt63I5F57/s4RzsvqcgdXh8NMzfEz8NKKqYHQeYHvN6ky0MJEUbceGLUxYoia/F6u+ariKNoKOb3WL3zkrIer1lFsZLcWJO2mZR38/3Q4BbcA07Iq8uOg2sswCzcBxjM52Y5XrMM2awebXW8nJTFeqLP8Dq7HZI7boekMtYTrF+nyWZeneZ3DfPpM8/HY2ZErj3xsiY0K8q/r6FDvxCvh/T6S4MXXnjhhRdeBC+88MILL7wIXnjhhdcj51987R/KzzMKWAAAAABJRU5ErkJggg==', ], 'center' => [ 'name' => __( 'Center', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAAAAACfVToRAAAEtElEQVR42u3cLXPjPBSG4f3/9KGGgoFmhmZlspvUabITsp6XGJkZnRdIdpw2X91ku9noflA6kxZcI8lHR3J/GPlKfkCAF1544YUXwQsvvPDCCy+CF1544YUX+fNe//38a8ELL7zwwgsvvPDCCy+88MILL7zwwgsvvPDCCy+88MILL7zwwgsvvPDCCy+88MILr4fxer8l28S8tk1d3ZT6PSWv7Wt1c5qEvO7AVVXrZLzW9+Cq6mS8VnfxOj3Ans3rPlynV7Dn9KrXv1tNrJL0Wv52PfqOF1544fUoXlu8rvfaruqqqpstXld5beLO+3WL1zVeU6NihdcVXrO95Bavy16r8/ubt6re4DXzWp71WlXVEbCUvd7O9RvC4PsExvp1fP0a5+pHsKSfj1Ov9e10m+wDWNJeYy9/da6reAiWeH3fvFbVcn2+CXsAxn77cs96DobXFS3+GRhe15yI7MHwuuoAaQLDa1PX68vnbSNY8l6bel7enz6erLd47Vtg68unue947TuGAezs4TdeM66qWl+6K4DXnKuq1heuVuD1s/nKlQm88MILL7zwSsRrvfxCNnhxPwcvvPDCCy+85u8rLH83dWJeNe93fMnrTu8PbVLx2tyFa5nO+4/NHbjqTULvIzd/kusZ33ffrG5a9F/PXtd/Qi/+nwJeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeKXo1f36a/knvZ4yeOGFF1544UXwwgsvvPDC61viFJPvLn/ZSzleY8rbvcpr/sqzeMnjdY1XbmbWZNICr6u9zEsazHs/dLlKs95Lku/D15qF5JrjXt5JKneJeTWSepPUSCqtHSfp6CBJmZSbSWrNrJfUm/VuWv7it5TQ+AooKvuwnHlJXbDcBbVPXk4qzHaZ1KTkFdcvSSoHsyJOrFIqzFx8FuSfvRrJmZm9SEWCz0dFvixOxFbS0IdRNq73B16F9JJoPVGamaRmP9fih3acY81nLxd+IT2vUN8frk14nV7vQ6LF4Xwcjs7HTlJveZyPvfc+Ya/Zep+bLeJ6vxi9/FSA+Lje+3TW+2Ne3ad6wk/1xEJyvXVOUm9DrCfCL5bfvyF/DC/bHatXw/hqwg/BK7iNjwufTr36wevofqj3vjGz3UKSH8ZnQtgPtVPV+9Re/3zwwgsvvPDCi+CFF1544fWd8TleeN2YZjHrT/hMcuG+QPsyb1zgFZPHtlZr+zNZ148trrExhlfMy3Rs1Jstxs9u30eMzS+8zCwc/hRhML2M7ehC0q6QXOfz3n1/p/6RvcZjjEIqpsOPTPJO8uZz81KG15QyHpOVUmEuLlZO8ovoxfPxIDvv25HIvPd9nKOdl1TkDq9Tw8wN8fOwkIrpQZD5Aa8P6fJQQoQRN54kdbGiyFq8Pq75KuIoGor5/VbvvKSsx2tWUSwkN9akbSbl3Xw/NLgr7gcn5NVl+8E1FmAW7gkM5nOzHK9ZhmxWj7baX1rKYj3RZ3gd3Q7J7bdDUhnrCdavw2Qzr07zO4j59Jnn4z4zItceeFkTmhXlgzR06BfilbrXIwUvvPDCCy+8CF544YUXXngRvPDCC69nzv/F6x/Kmshd1QAAAABJRU5ErkJggg==', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'wooscardcontentalingcenter' ), ], 'right' => [ 'name' => __( 'Right', 'neve' ), 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAS8AAADYCAAAAACfVToRAAAEs0lEQVR42u3cLXPrOhSF4fP/6aKGgoFmhmZlspvUaXIm5HguMTIz2hdIdpw2X23SaRu9C6UzacEzkry1JfePkY/kDwR44YUXXngRvPDCCy+88CJ44YUXXniRr/f67++3BS+88MILL7zwwgsvvPDCCy+88MILL7zwwgsvvPDCCy+88MILL7zwwgsvvPDCCy+8fozX6y3ZJua1berqptSvKXltn6ub0yTkdQeuqlon47W+B1dVJ+O1uovX6QH2aF734Tq9gj2mV73+bDWxStJr+el69BUvvPDC66d4bfG63mu7qquqbrZ4XeW1iTvv5y1e13hNjYoVXld4zfaSW7wue63O729eqnqD18xredZrVVVHwFL2ejnXbwiD7x0Y69fx9Wucq2/Bkn4+Tr3Wl9NtsjdgSXuNvfzVua7iIVji9X3zXFXL9fkm7AEY++3LPes5GF5XtPhnYHhdcyKyB8PrqgOkCQyvTV2vL5+3jWDJe23qeXl/+niy3uK1b4GtL5/mvuK17xgGsLOH33jNuKpqfemuAF5zrqpaX7hagdff5iNXJvDCCy+88MIrEa/18gPZ4MX9HLzwwgsvvPCav6+w/GzqxLxq3u/4kNed3h/apOK1uQvXMp33H5s7cNWbhN5Hbr6S6xHfd9+sblr0n89e139AL/6fAl544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF1544YUXXnjhhRdeeOGFF154pejV/fu2/EqvhwxeeOGFF154EbzwwgsvvPD6rjjF5LvLX/ZSjteY8nav8pq/8ihe8nhd45WbmTWZtMDrai/zkgbz3g9drtKs95Lk+/C1ZiG55riXd5LKXWJejaTeJDWSSmvHSTo6SFIm5WaSWjPrJfVmvZuWv/gtJTS+AorKPixnXlIXLHdB7Z2XkwqzXSY1KXnF9UuSysGsiBOrlAozF58F+XuvRnJmZk9SkeDzUZEvixOxlTT0YZSN6/2BVyE9JVpPlGYmqdnPtfihHedY897LhV9IzyvU94drE16n1/uQaHE4H4ej87GT1Fse52PvvU/Ya7be52aLuN4vRi8/FSA+rvc+nfX+mFf3rp7wUz2xkFxvnZPU2xDrifCL5RdvyH+sl+2O1athfDXhh+AV3MbHhU+nXn3jdXQ/1HvfmNluIckP4zMh7Ifaqep9aK/fFbzwwgsvvPAieOGFF154/dD4HC+8bkyzmPUtfCa5cI+gfZo3NPCKyWO7q7X9Wa3rx9bX2DDDK+ZpOk7qzRbjZ7fvL8amGF5mFg6FijCYnsY2dSFpV0iu83nvvrSD/+u8xuONQiqmQ5FM8k7y5nPzUobXlDIen5VSYS4uVk7yi+jF8/EgO+/bkci8932co52XVOQOr1PDzA3x87CQiulBkPkBrzfp8lBChBE3njB1saLIWrzervkq4igaivm9V++8pKzHa1ZRLCQ31qRtJuXdfD80uCvuDSfk1WX7wTUWYBbuDwzmc7Mcr1mGbFaPttpfZspiPdFneB3dDsntt0NSGesJ1q/DZDOvTvO7ifn0mefjPjMi1x54WROaFeVXNnToF+KF188JXnjhhRdeeBG88MILL7zwInjhhRdej5z/AdA+H8o+3vutAAAAAElFTkSuQmCC', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'wooscardcontentalingright' ), ], 'inline' => [ 'name' => __( 'Left', 'neve' ) . ' / ' . __( 'Right', 'neve' ), 'url' => 'data:image/png;base64,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', 'upsellUrl' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'wooscardcontentalinginline' ), ], ], ], '\Neve\Customizer\Controls\React\Radio_Image' ) ); } /** * Sanitize checkout layout that forcefully updates the selection as standard. * * @return string */ public function sanitize_checkout_layout() { return 'standard'; } /** * Add upsells section */ private function section_upsells() { $this->add_section( new Section( 'neve_free_pro_upsell', array( 'priority' => -100, 'title' => esc_html__( 'Neve PRO Features', 'neve' ), 'url' => $this->upsell_url, ), 'Neve\Customizer\Controls\React\Upsell_Section' ) ); } /** * Add upsells controls */ private function control_upsells() { $this->add_control( new Control( 'neve_upsell_main_control', [ 'sanitize_callback' => 'sanitize_text_field' ], [ 'text' => esc_html__( 'Neve PRO Features', 'neve' ), 'button_text' => esc_html__( 'Learn More', 'neve' ), 'section' => 'neve_free_pro_upsell', 'priority' => PHP_INT_MIN, 'link' => $this->upsell_url, ], 'Neve\Customizer\Controls\Simple_Upsell' ) ); $upsells = []; $upsells_banners = []; $upsells_banners['blog_archive'] = [ 'text' => __( 'More blog layout customization options available in PRO', 'neve' ), 'button_text' => __( 'Learn More', 'neve' ), 'use_logo' => true, 'section' => 'neve_blog_archive_layout', ]; $upsells_banners['single_post'] = [ 'text' => __( 'More single post components available in PRO', 'neve' ), 'button_text' => __( 'Learn More', 'neve' ), 'use_logo' => true, 'section' => 'neve_single_post_layout', ]; $hfg_header = 'hfg_header'; $hfg_header_text = __( 'Extend your header with more components and settings, build sticky/transparent headers or display them conditionally.', 'neve' ); $hfg_header_button = __( 'Get the PRO version!', 'neve' ); $upsells_banners[ $hfg_header ] = [ 'text' => $hfg_header_text, 'button_text' => $hfg_header_button, 'use_logo' => true, 'panel' => $hfg_header, 'type' => 'section', ]; foreach ( [ 'top', 'main', 'bottom', 'sidebar' ] as $section ) { $section_id = $hfg_header . '_layout_' . $section; $upsells_banners[ $section_id ] = [ 'text' => $hfg_header_text, 'button_text' => $hfg_header_button, 'use_logo' => true, 'section' => $section_id, ]; } $hfg_footer = 'hfg_footer'; $hfg_footer_text = __( 'Neve PRO Features', 'neve' ); $hfg_footer_button = __( 'Get the PRO version!', 'neve' ); $upsells_banners[ $hfg_footer ] = [ 'text' => $hfg_footer_text, 'button_text' => $hfg_footer_button, 'use_logo' => true, 'panel' => $hfg_footer, 'type' => 'section', ]; foreach ( [ 'top', 'main', 'bottom' ] as $section ) { $section_id = $hfg_footer . '_layout_' . $section; $upsells_banners[ $section_id ] = [ 'text' => $hfg_footer_text, 'button_text' => $hfg_footer_button, 'use_logo' => true, 'section' => $section_id, ]; } if ( class_exists( 'WooCommerce', false ) ) { $upsells['product_catalog'] = [ 'text' => __( 'More product catalog options available in PRO', 'neve' ), 'button_text' => __( 'Learn More', 'neve' ), 'section' => 'woocommerce_product_catalog', ]; $upsells['woocommerce_checkout'] = [ 'text' => __( 'More checkout options available in PRO', 'neve' ), 'button_text' => __( 'Learn More', 'neve' ), 'section' => 'woocommerce_checkout', ]; $upsells['single_product_layout'] = [ 'text' => __( 'More single product options available in PRO', 'neve' ), 'button_text' => __( 'Learn More', 'neve' ), 'section' => 'neve_single_product_layout', ]; $upsells['typography'] = [ 'text' => __( 'WooCommerce typography options available in PRO', 'neve' ), 'button_text' => __( 'Learn More', 'neve' ), 'panel' => 'neve_typography', 'type' => 'section', ]; } $is_dismissed = get_transient( 'upsell_dismiss_banner_customizer' ); if ( $is_dismissed === false ) { foreach ( $upsells_banners as $id => $args ) { if ( isset( $args['type'] ) && $args['type'] === 'section' ) { $section_id = 'neve_' . $id . '_upsell_section'; $this->add_section( new Section( $section_id, array_merge( $args, [ 'type' => 'neve_upsell_banner_section', 'priority' => 10000, 'nonce' => wp_create_nonce( 'neve-upsell-banner-nonce' ), 'url' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'panel-' . $args['panel'] ), ] ), '\Neve\Customizer\Controls\React\Upsell_Banner_Section' ) ); continue; } $control_id = 'neve_' . $id . '_upsell_banner_control'; $this->add_control( new Control( $control_id, [ 'sanitize_callback' => 'sanitize_text_field' ], array_merge( $args, [ 'type' => 'neve_upsell_banner', 'priority' => 10000, 'nonce' => wp_create_nonce( 'neve-upsell-banner-nonce' ), 'url' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'upsell-banner-customizer-section-' . $args['section'] ), ] ), '\Neve\Customizer\Controls\React\Upsell_Banner' ) ); } } foreach ( $upsells as $id => $args ) { if ( isset( $args['type'] ) && $args['type'] === 'section' ) { $this->add_section( new Section( 'neve_' . $id . '_upsell_section', array_merge( $args, [ 'type' => 'nv_simple_upsell_section', 'priority' => 10000, 'link' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'panel-' . $args['panel'] ), ] ), '\Neve\Customizer\Controls\Simple_Upsell_Section' ) ); return false; } $this->add_control( new Control( 'neve_' . $id . '_upsell', [ 'sanitize_callback' => 'sanitize_text_field' ], array_merge( $args, [ 'priority' => 10000, 'link' => tsdk_utmify( 'https://themeisle.com/themes/neve/upgrade/', 'section-' . $args['section'] ), ] ), 'Neve\Customizer\Controls\Simple_Upsell' ) ); } } } form_fields.php 0000666 00000043472 15226760542 0007575 0 ustar 00 <?php /** * Form Fields section. * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use HFG\Traits\Core; use Neve\Core\Settings\Config; use Neve\Core\Settings\Mods; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Section; /** * Class Form_Fields * * @package Neve\Customizer\Options */ class Form_Fields extends Base_Customizer { use Core; /** * Customizer section slug. * * @var string */ private $section_id = 'neve_form_fields_section'; /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { $this->add_form_section(); $this->add_form_fields_controls(); $this->add_input_text_controls(); $this->add_form_labels_controls(); $this->add_button_controls(); } /** * Add section. */ private function add_form_section() { $this->add_section( new Section( $this->section_id, [ 'priority' => 45, 'description_hidden' => true, 'description' => __( 'Customize the general design of the form elements across the site.', 'neve' ) . ' ' . neve_external_link( 'https://docs.themeisle.com/article/1341-neve-form-fields', 'Learn More' ), 'title' => esc_html__( 'Form Fields', 'neve' ), ] ) ); } /** * Form fields controls. */ private function add_form_fields_controls() { $this->add_control( new Control( 'neve_form_fields_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'Form Fields', 'neve' ), 'section' => $this->section_id, 'priority' => 10, 'class' => 'form-fields-accordion', 'accordion' => true, 'controls_to_wrap' => 5, ], 'Neve\Customizer\Controls\Heading' ) ); // Padding $default_padding = Mods::get_alternative_mod_default( Config::MODS_FORM_FIELDS_PADDING ); $this->add_control( new Control( Config::MODS_FORM_FIELDS_PADDING, [ 'sanitize_callback' => [ $this, 'sanitize_spacing_array' ], 'transport' => $this->selective_refresh, 'default' => $default_padding, ], [ 'label' => esc_html__( 'Field Padding', 'neve' ), 'section' => $this->section_id, 'priority' => 15, 'units' => [ 'px', 'em', 'rem' ], 'default' => $default_padding, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'selector' => 'body', 'vars' => '--formfieldpadding', 'suffix' => 'px', ], 'responsive' => false, 'directional' => true, 'template' => ' body form input:read-write, body form textarea, body form select, body form select option, body form.wp-block-search input.wp-block-search__input, .woocommerce-cart table.cart td.actions .coupon .input-text, .woocommerce-page .select2-container--default .select2-selection--single, .woocommerce-page .woocommerce form .form-row input.input-text, .woocommerce-page .woocommerce form .form-row textarea, .widget select, .wc-block-product-search form input.wc-block-product-search__field { padding-top: {{value.top}}; padding-right: {{value.right}}; padding-bottom: {{value.bottom}}; padding-left: {{value.left}}; } form.search-form input[type="search"], form.woocommerce-product-search input[type="search"] { padding-right: calc({{value.right}} + 33px); }', ], ], '\Neve\Customizer\Controls\React\Nr_Spacing' ) ); // Background color $this->add_control( new Control( Config::MODS_FORM_FIELDS_BACKGROUND_COLOR, [ 'sanitize_callback' => 'neve_sanitize_colors', 'default' => 'var(--nv-site-bg)', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Field Background Color', 'neve' ), 'section' => $this->section_id, 'priority' => 17, 'default' => 'var(--nv-site-bg)', 'input_attrs' => [ 'allow_gradient' => true, ], 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'selector' => 'body', 'vars' => '--formfieldbgcolor', ], 'template' => ' body form input:read-write, body form textarea, body form select, body form select option, body form.wp-block-search input.wp-block-search__input, .woocommerce-cart table.cart td.actions .coupon .input-text, .woocommerce-page .select2-container--default .select2-selection--single, .woocommerce-page .woocommerce form .form-row input.input-text, .woocommerce-page .woocommerce form .form-row textarea, .widget select, .wc-block-product-search form input.wc-block-product-search__field { background-color: {{value}}; }', ], ], 'Neve\Customizer\Controls\React\Color' ) ); // Border width $default_width = Mods::get_alternative_mod_default( Config::MODS_FORM_FIELDS_BORDER_WIDTH ); $this->add_control( new Control( Config::MODS_FORM_FIELDS_BORDER_WIDTH, [ 'sanitize_callback' => [ $this, 'sanitize_spacing_array' ], 'transport' => $this->selective_refresh, 'default' => $default_width, ], [ 'label' => esc_html__( 'Border Width', 'neve' ), 'section' => $this->section_id, 'priority' => 18, 'units' => [ 'px', 'em', 'rem' ], 'default' => $default_width, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'selector' => 'body', 'vars' => '--formfieldborderwidth', 'suffix' => 'px', ], 'responsive' => false, 'directional' => true, 'template' => ' body form input:read-write, body form textarea, body form select, body form select option, body form.wp-block-search input.wp-block-search__input, .woocommerce-cart table.cart td.actions .coupon .input-text, .woocommerce-page .select2-container--default .select2-selection--single, .woocommerce-page .woocommerce form .form-row input.input-text, .woocommerce-page .woocommerce form .form-row textarea, .widget select, .wc-block-product-search form input.wc-block-product-search__field { border-top-width: {{value.top}}; border-right-width: {{value.right}}; border-bottom-width: {{value.bottom}}; border-left-width: {{value.left}}; }', ], ], '\Neve\Customizer\Controls\React\Nr_Spacing' ) ); // Border radius $this->add_control( new Control( Config::MODS_FORM_FIELDS_BORDER_RADIUS, [ 'sanitize_callback' => [ $this, 'sanitize_spacing_array' ], 'transport' => $this->selective_refresh, 'default' => false, ], [ 'label' => esc_html__( 'Border Radius', 'neve' ), 'section' => $this->section_id, 'priority' => 19, 'units' => [ 'px', 'em', 'rem' ], 'default' => [ 'top' => '3', 'right' => '3', 'left' => '3', 'bottom' => '3', 'unit' => 'px', ], 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'selector' => 'body', 'vars' => '--formfieldborderradius', 'suffix' => 'px', ], 'responsive' => false, 'directional' => true, 'template' => ' body form input:read-write, body form textarea, body form select, body form select option, body form.wp-block-search input.wp-block-search__input, .woocommerce-cart table.cart td.actions .coupon .input-text, .woocommerce-page .select2-container--default .select2-selection--single, .woocommerce-page .woocommerce form .form-row input.input-text, .woocommerce-page .woocommerce form .form-row textarea, .widget select, .wc-block-product-search form input.wc-block-product-search__field { border-top-right-radius: {{value.top}}; border-bottom-right-radius: {{value.right}}; border-bottom-left-radius: {{value.bottom}}; border-top-left-radius: {{value.left}}; }', ], ], '\Neve\Customizer\Controls\React\Nr_Spacing' ) ); // Border color $this->add_control( new Control( Config::MODS_FORM_FIELDS_BORDER_COLOR, [ 'sanitize_callback' => 'neve_sanitize_colors', 'default' => '#dddddd', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Border Color', 'neve' ), 'section' => $this->section_id, 'priority' => 20, 'default' => '#dddddd', 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'selector' => 'body', 'vars' => '--formfieldbordercolor', ], 'template' => ' body form input:read-write, body form textarea, body form select, body form select option, body form.wp-block-search input.wp-block-search__input, .woocommerce-cart table.cart td.actions .coupon .input-text, .woocommerce-page .select2-container--default .select2-selection--single, .woocommerce-page .woocommerce form .form-row input.input-text, .woocommerce-page .woocommerce form .form-row textarea, .widget select, .wc-block-product-search form input.wc-block-product-search__field { border-color: {{value}}; }', ], ], 'Neve\Customizer\Controls\React\Color' ) ); } /** * Form inputs controls. */ private function add_input_text_controls() { $this->add_control( new Control( 'neve_input_text_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'Input Text', 'neve' ), 'section' => $this->section_id, 'priority' => 30, 'class' => 'form-input-accordion', 'accordion' => true, 'expanded' => false, 'controls_to_wrap' => 2, ], 'Neve\Customizer\Controls\Heading' ) ); // Field text color $this->add_control( new Control( Config::MODS_FORM_FIELDS_COLOR, [ 'sanitize_callback' => 'neve_sanitize_colors', 'default' => 'var(--nv-text-color)', 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Color', 'neve' ), 'section' => $this->section_id, 'priority' => 31, 'default' => 'var(--nv-text-color)', 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'selector' => 'body', 'vars' => '--formfieldcolor', ], 'template' => ' body form input:read-write, body form textarea, body form select, body form select option, body form.wp-block-search input.wp-block-search__input, .woocommerce-cart table.cart td.actions .coupon .input-text, .woocommerce-page .select2-container--default .select2-selection--single, .woocommerce-page .woocommerce form .form-row input.input-text, .woocommerce-page .woocommerce form .form-row textarea, .widget select, .wc-block-product-search form input.wc-block-product-search__field { color: {{value}}; }', ], ], 'Neve\Customizer\Controls\React\Color' ) ); // Field typeface $this->add_control( new Control( Config::MODS_FORM_FIELDS_TYPEFACE, [ 'transport' => $this->selective_refresh, ], [ 'priority' => 32, 'section' => $this->section_id, 'input_attrs' => array( 'disable_transform' => true, 'default_is_empty' => true, 'size_units' => [ 'px', 'em', 'rem' ], 'weight_default' => 'none', 'size_default' => array( 'suffix' => array( 'mobile' => 'px', 'tablet' => 'px', 'desktop' => 'px', ), 'mobile' => '', 'tablet' => '', 'desktop' => '', ), 'line_height_default' => array( 'mobile' => '', 'tablet' => '', 'desktop' => '', ), 'letter_spacing_default' => array( 'mobile' => '', 'tablet' => '', 'desktop' => '', ), ), 'type' => 'neve_typeface_control', 'font_family_control' => 'neve_body_font_family', 'refresh_on_reset' => true, 'live_refresh_selector' => ' form input:read-write, form textarea, form select, form select option, form.wp-block-search input.wp-block-search__input, .woocommerce-cart table.cart td.actions .coupon .input-text, .woocommerce-page .select2-container--default .select2-selection--single, .woocommerce-page .woocommerce form .form-row input.input-text, .woocommerce-page .woocommerce form .form-row textarea, .widget select, .wc-block-product-search form input.wc-block-product-search__field ', 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => [ '--formfieldtexttransform' => 'textTransform', '--formfieldfontweight' => 'fontWeight', '--formfieldfontsize' => [ 'key' => 'fontSize', 'responsive' => true, ], '--formfieldlineheight' => [ 'key' => 'lineHeight', 'responsive' => true, ], '--formfieldletterspacing' => [ 'key' => 'letterSpacing', 'suffix' => 'px', 'responsive' => true, ], ], 'selector' => 'body', ], ], ], '\Neve\Customizer\Controls\React\Typography' ) ); } /** * Form labels controls. */ private function add_form_labels_controls() { $this->add_control( new Control( 'neve_form_labels_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'Form Labels', 'neve' ), 'section' => $this->section_id, 'priority' => 50, 'class' => 'form-labels-accordion', 'accordion' => true, 'expanded' => false, 'controls_to_wrap' => 1, ], 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( Config::MODS_FORM_FIELDS_LABELS_TYPEFACE, [ 'transport' => $this->selective_refresh, ], [ 'priority' => 52, 'section' => $this->section_id, 'input_attrs' => [ 'default_is_empty' => true, 'size_units' => [ 'px', 'em', 'rem' ], 'weight_default' => 'none', 'size_default' => [ 'suffix' => [ 'mobile' => 'px', 'tablet' => 'px', 'desktop' => 'px', ], 'mobile' => '', 'tablet' => '', 'desktop' => '', ], 'line_height_default' => [ 'mobile' => '', 'tablet' => '', 'desktop' => '', ], 'letter_spacing_default' => [ 'mobile' => '', 'tablet' => '', 'desktop' => '', ], ], 'type' => 'neve_typeface_control', 'font_family_control' => 'neve_body_font_family', 'refresh_on_reset' => true, 'live_refresh_selector' => 'form label, body .wpforms-container .wpforms-field-label, .woocommerce form .form-row label', 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => [ '--formlabeltexttransform' => 'textTransform', '--formlabelfontweight' => 'fontWeight', '--formlabelfontsize' => [ 'key' => 'fontSize', 'responsive' => true, ], '--formlabellineheight' => [ 'key' => 'lineHeight', 'responsive' => true, ], '--formlabelletterspacing' => [ 'key' => 'letterSpacing', 'suffix' => 'px', 'responsive' => true, ], ], 'selector' => 'body', ], ], ], '\Neve\Customizer\Controls\React\Typography' ) ); } /** * Form button controls. */ private function add_button_controls() { $this->add_control( new Control( 'neve_form_button_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], array( 'label' => esc_html__( 'Button', 'neve' ), 'section' => $this->section_id, 'priority' => 70, 'class' => 'form-button-accordion', 'accordion' => true, 'expanded' => false, 'controls_to_wrap' => 1, ), 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_form_button_type', [ 'sanitize_callback' => 'neve_sanitize_button_type', 'default' => 'primary', ], [ 'label' => __( 'Button Style', 'neve' ), 'priority' => 71, 'section' => $this->section_id, 'type' => 'neve_inline_select', 'options' => [ 'primary' => __( 'Primary', 'neve' ), 'secondary' => __( 'Secondary', 'neve' ), ], 'default' => 'primary', 'link' => [ 'focus' => [ 'section', 'neve_buttons_section' ], 'string' => esc_html__( 'Customize the default button styles', 'neve' ), ], ], 'Neve\Customizer\Controls\React\Inline_Select' ) ); } } buttons.php 0000666 00000011611 15226760542 0006770 0 ustar 00 <?php /** * Buttons section. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 20/08/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Core\Settings\Config; use Neve\Core\Settings\Mods; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Section; /** * Class Buttons * * @package Neve\Customizer\Options */ class Buttons extends Base_Customizer { /** * Customizer section slug. * * @var string */ private $section_id = 'neve_buttons_section'; /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { $this->add_section( new Section( $this->section_id, array( 'priority' => 40, 'title' => esc_html__( 'Buttons', 'neve' ), ) ) ); $this->add_control( new Control( 'neve_buttons_generic_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'General', 'neve' ), 'section' => $this->section_id, 'class' => 'buttons-general-accordion', 'accordion' => true, 'expanded' => true, 'controls_to_wrap' => 2, ], 'Neve\Customizer\Controls\Heading' ) ); $mod_key = Config::MODS_BUTTON_PRIMARY_PADDING; $defaults = Mods::get_alternative_mod_default( Config::MODS_BUTTON_PRIMARY_PADDING ); $this->add_control( new Control( $mod_key, array( 'default' => $defaults, ), array( 'label' => __( 'Padding', 'neve' ), 'sanitize_callback' => array( $this, 'sanitize_spacing_array' ), 'section' => $this->section_id, 'input_attrs' => [ 'units' => [ 'px', 'em', 'rem' ], 'min' => 0, ], 'default' => $defaults, ), '\Neve\Customizer\Controls\React\Spacing' ) ); $this->add_control( new Control( Config::MODS_BUTTON_TYPEFACE, [ 'transport' => $this->selective_refresh, ], [ 'label' => esc_html__( 'Button Text', 'neve' ), 'section' => $this->section_id, 'input_attrs' => array( 'size_units' => [ 'px', 'em', 'rem' ], 'weight_default' => 700, 'size_default' => array( 'suffix' => array( 'mobile' => 'px', 'tablet' => 'px', 'desktop' => 'px', ), 'mobile' => '', 'tablet' => '', 'desktop' => '', ), 'line_height_default' => array( 'mobile' => '', 'tablet' => '', 'desktop' => '', ), 'letter_spacing_default' => array( 'mobile' => '', 'tablet' => '', 'desktop' => '', ), ), 'type' => 'neve_typeface_control', 'font_family_control' => 'neve_body_font_family', 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => [ '--btnfs' => [ 'key' => 'fontSize', 'responsive' => true, 'suffix' => 'px', ], '--btnlineheight' => [ 'key' => 'lineHeight', 'responsive' => true, ], '--btnletterspacing' => [ 'key' => 'letterSpacing', 'responsive' => true, 'suffix' => 'px', ], '--btntexttransform' => [ 'key' => 'textTransform', ], '--btnfontweight' => [ 'key' => 'fontWeight', ], ], 'selector' => 'body', ], ], 'refresh_on_reset' => true, ], '\Neve\Customizer\Controls\React\Typography' ) ); $buttons = [ 'button' => __( 'Primary Button', 'neve' ), 'secondary_button' => __( 'Secondary Button', 'neve' ), ]; foreach ( $buttons as $button => $heading_text ) { $this->add_control( new Control( 'neve_' . $button . '_appearance_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html( $heading_text ), 'section' => $this->section_id, 'class' => 'buttons-' . $button . '-appearance-accordion', 'accordion' => true, 'controls_to_wrap' => 1, 'expanded' => false, ], 'Neve\Customizer\Controls\Heading' ) ); $mod_key = 'neve_' . $button . '_appearance'; $defaults = neve_get_button_appearance_default( $button ); $this->add_control( new Control( $mod_key, [ 'sanitize_callback' => 'neve_sanitize_button_appearance', 'default' => $defaults, ], [ 'default_vals' => $defaults, 'label' => __( 'Button Appearance', 'neve' ), 'section' => $this->section_id, ], '\Neve\Customizer\Controls\React\Button_Appearance' ) ); } } } layout_single_product.php 0000666 00000007024 15226760542 0011713 0 ustar 00 <?php /** * Single post layout section. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 20/08/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Customizer\Base_Customizer; use Neve\Customizer\Types\Control; use Neve\Customizer\Types\Section; /** * Class Layout_Single_Product * * @package Neve\Customizer\Options */ class Layout_Single_Product extends Base_Customizer { /** * Add customizer controls. */ public function add_controls() { if ( ! $this->should_load() ) { return; } $this->section_single_product(); $this->exclusive_products_controls(); } /** * Check if the controls for Single Product should load. */ private function should_load() { return class_exists( 'WooCommerce', false ); } /** * Add single product layout section. */ private function section_single_product() { $this->add_section( new Section( 'neve_single_product_layout', array( 'priority' => 65, 'title' => esc_html__( 'Single Product', 'neve' ), 'panel' => 'woocommerce', ) ) ); } /** * Add customizer controls for exclusive products section. */ private function exclusive_products_controls() { $this->add_control( new Control( 'neve_exclusive_products_heading', array( 'sanitize_callback' => 'sanitize_text_field', 'transport' => $this->selective_refresh, ), array( 'label' => esc_html__( 'Exclusive Products', 'neve' ), 'section' => 'neve_single_product_layout', 'priority' => 200, 'class' => 'exclusive-products-accordion', 'accordion' => true, 'controls_to_wrap' => 2, 'expanded' => true, ), 'Neve\Customizer\Controls\Heading' ) ); $this->add_control( new Control( 'neve_exclusive_products_title', array( 'sanitize_callback' => 'sanitize_text_field', ), array( 'priority' => 210, 'section' => 'neve_single_product_layout', 'label' => esc_html__( 'Title', 'neve' ), 'type' => 'text', ) ) ); $product_cat = $this->get_shop_categories(); $this->add_control( new Control( 'neve_exclusive_products_category', array( 'default' => '-', 'sanitize_callback' => array( $this, 'sanitize_categories' ), ), array( 'label' => esc_html__( 'Category', 'neve' ), 'section' => 'neve_single_product_layout', 'priority' => 220, 'type' => 'select', 'choices' => $product_cat, ) ) ); } /** * Get shop categories. * * @return array */ private function get_shop_categories() { $categories = array( '-' => esc_html__( 'None', 'neve' ), 'all' => esc_html__( 'All', 'neve' ), ); $product_categories = get_categories( array( 'taxonomy' => 'product_cat', 'hide_empty' => 0, 'title_li' => '', ) ); if ( empty( $product_categories ) ) { return $categories; } foreach ( $product_categories as $category ) { $term_id = $category->term_id; $cat_name = $category->name; if ( empty( $term_id ) || empty( $cat_name ) ) { continue; } $categories[ $term_id ] = $cat_name; } return $categories; } /** * Sanitize categories value. * * @param string $value Value from the control. * * @return string */ public function sanitize_categories( $value ) { $categories = $this->get_shop_categories(); if ( ! array_key_exists( $value, $categories ) ) { return '-'; } return $value; } } rtl.php 0000666 00000011602 15226760542 0006073 0 ustar 00 <?php /** * Rtl customizer compatibility. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 24/09/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use Neve\Customizer\Base_Customizer; /** * Class Rtl * * @package Neve\Customizer\Options */ class Rtl extends Base_Customizer { /** * Abstract method that must be implemented. */ public function add_controls() {} /** * Change controls */ protected function change_controls() { if ( ! is_rtl() ) { return; } $this->change_customizer_object( 'control', 'neve_navigation_layout', 'choices', $this->rtl_navigation_layout_choices() ); $this->change_customizer_object( 'control', 'neve_top_bar_layout', 'choices', $this->rtl_top_bar_layout_choices() ); $sidebar_layout_controls = array( 'neve_default_sidebar_layout', 'neve_blog_archive_sidebar_layout', 'neve_single_post_sidebar_layout', ); if ( class_exists( 'WooCommerce', false ) ) { $sidebar_layout_controls = array_merge( $sidebar_layout_controls, array( 'neve_shop_archive_sidebar_layout', 'neve_single_product_sidebar_layout', ) ); } foreach ( $sidebar_layout_controls as $control_id ) { $this->change_customizer_object( 'control', $control_id, 'choices', $this->rtl_sidebar_layout_choices() ); } } /** * Get the rtl navigation layout choices. * * @return array */ private function rtl_navigation_layout_choices() { return array( 'left' => array( 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqCAMAAABpj1iyAAAADFBMVEUAhbo+yP/V1dX///9l36pFAAAAdUlEQVR4Ae3VMQrAMAwEQSX5/5/TujIYJPDBbKduqlN9V4aFhTXYsy+JVWsNdz4LCwtrJiyvGgsLCwsLCwsrioWFhYWFhYWFHfVOhoWFFTwQWFhYPYuAhYVlt7CwsLAOpxMLCwsrdE6xsLCwsLCwsLCwsLCwfkRXrgTYLelPAAAAAElFTkSuQmCC', ), 'center' => array( 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqAgMAAAAjP0ATAAAADFBMVEX////V1dUAhbo+yP8aB7nsAAAARElEQVRYR2NgGKngPwT8GVU2BJQNb6C1atUCfHjEKRsFo2BEANFQrCBg+CkbWYDIwBgGykYBBYDIkB1VNgpGwSgYMAAAzIYr4wYj4sEAAAAASUVORK5CYII=', ), 'right' => array( 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqAgMAAAAjP0ATAAAADFBMVEX////V1dUAhbo+yP8aB7nsAAAARklEQVRYhWNgGEGA/z8EHKC+MqZVq1ah4xGtjOLgHQWjYBSMgmENREOxgoDhp2xkASIDYxgoGwUUACJDdlTZKBgFo2DAAAAZAflVkm2NtwAAAABJRU5ErkJggg==', ), ); } /** * Get the rtl top_bar layout choices. * * @return array */ private function rtl_top_bar_layout_choices() { return array( 'content-menu' => array( 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqCAMAAABpj1iyAAAAXVBMVEUAbq4AebMAe7QAe7UAhboFfLQFh7sjjr49l8NToMhmqMx3sNGGuNWVwNqjyN6wz+K81ufB3+3B4e7C4u7I3evR6fPU5O/V6/Tf6/Pq8vf1+fv1+vz6/f7+//////+gH6NhAAABU0lEQVR42u3UzU7DMBAE4AID/k8CBGObsu//mN0kVRMEUukl6mFGSjbjXD5Zlg9ylyGLLLLIIossssgiiyyyyCKLLLLIIossssgiiyyyyCKLLLLIug8WIH/EI19jvb9d8vol37fUH8l1Hm0eNdf5owDLemnTv1ykTNOhL1dYzw+XHD7k+HhD3aSzQGhSIuBHrdAeRTyATmSwMNoyjIGtOgF/HfWCS54+5XhLXVNhkndNInyEVZZ2oJx3qxnTOYwTJxn0y27twYoY1CYNRiRgVFbS2Z3P1gDrLYKyrPTwy9nag5XQSy3SzMzKyur0WVnGe5+U5SXvyapAgKkS4QKsrCyHECdtcq6trA7W7XLkewc7iLRoEMqGNWrXt4NJG1a1sHWfC6LIekFss/Rfq7zlySKLLLLIIossssgiiyyyyCKLLLLIIossssgiiyyyyCKLrP/mBGV6EYQ9BHpwAAAAAElFTkSuQmCC', ), 'menu-content' => array( 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqCAMAAABpj1iyAAAAXVBMVEUAbq4AebMAe7QAe7UAhboFfLQFh7sjjr49l8NToMhmqMx3sNGGuNWVwNqjyN6wz+K81ufB3+3B4e7C4u7I3evR6fPU5O/V6/Tf6/Pq8vf1+fv1+vz6/f7+//////+gH6NhAAABVklEQVR4Ae3VzU7DMBAE4AID/onjBCjBNmXe/zHZplEbqahShRRxmDl0Oz59slbOjv8yYoklllhiiSWWWGKJJZZYYoklllhiiSWWWGKJJZZYYokl1p8jFsBfEjFtxZrqPNo86lTnPwU4nZdGsk2F5TgDhsJV3t/Oef3i9z31Nit7oGssCYh7q7CeyAggk6OHszbBOfhqE4hc5fnhnN0HD4931JusCtfH0JgQE7yxrANlua3mXA7YHzm9w3B9Wy845+mThzvqbVbCaDY2OLIzQEZvMy+7NcJHj85YngPislsbsHoMrIXNzayJ2Uh5xXIxxt5YkdOWrAp0cJUJoYPnhRXQpaO2D6FdWBk+bMHiEOBHsiWHrqxYe+v2G+D6Fat6+LrBylsKVw/EKqd+fbrJA7FEHx+xxBJLLLHEEkssscQSSyyxxBJLLLHEEkssscQSSyyxxBLrBzxgEYQpIrleAAAAAElFTkSuQmCC', ), ); } /** * Get the sidebar layout choices. * * @return array */ private function rtl_sidebar_layout_choices() { return array( 'full-width' => array( 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqAQMAAABknzrDAAAABlBMVEX////V1dXUdjOkAAAAPUlEQVRIx2NgGAUkAcb////Y/+d/+P8AdcQoc8vhH/X/5P+j2kG+GA3CCgrwi43aMWrHqB2jdowEO4YpAACyKSE0IzIuBgAAAABJRU5ErkJggg==', ), 'left' => array( 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqAgMAAAAjP0ATAAAACVBMVEX///8+yP/V1dXG9YqxAAAAWUlEQVR42mNgGAUjB4iGgkEIzZStAoEVTECiQWsVkLdiECkboAABOmwBF9BtUGcOImUDEiCkJCQU0ECBslEvjHph1AujXhj1wqgXRr0w6oVRLwyEF0bBUAUAz/FTNXm+R/MAAAAASUVORK5CYII=', ), 'right' => array( 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAABqAgMAAAAjP0ATAAAACVBMVEX///8+yP/V1dXG9YqxAAAAWElEQVR42mNgGAXDE4RCQMDAKONaBQINWqtWrWBatQDIaxg8ygYqQIAOYwC6bwHUmYNH2eBPSMhgBQXKRr0w6oVRL4x6YdQLo14Y9cKoF0a9QCO3jYLhBADvmFlNY69qsQAAAABJRU5ErkJggg==', ), ); } } layout_single_post.php 0000666 00000044173 15226760542 0011226 0 ustar 00 <?php /** * Single post layout section. * * Author: Andrei Baicus <andrei@themeisle.com> * Created on: 20/08/2018 * * @package Neve\Customizer\Options */ namespace Neve\Customizer\Options; use HFG\Traits\Core; use Neve\Core\Settings\Config; use Neve\Customizer\Defaults\Layout; use Neve\Customizer\Types\Control; use Neve\Customizer\Defaults\Single_Post; /** * Class Layout_Single_Post * * @package Neve\Customizer\Options */ class Layout_Single_Post extends Base_Layout_Single { use Core; use Layout; use Single_Post; /** * Returns the post type. * * @return string */ public function get_post_type() { return 'post'; } /** * @return string */ public function get_cover_selector() { return '.single .nv-post-cover'; } /** * Function that should be extended to add customizer controls. * * @return void */ public function add_controls() { parent::add_controls(); $this->control_content_order(); $this->content_vspacing(); $this->add_subsections(); $this->header_layout(); $this->post_meta(); $this->comments(); add_action( 'customize_register', [ $this, 'adjust_headings' ], PHP_INT_MAX ); } /** * Add sections headings. */ private function add_subsections() { $headings = [ 'page_elements' => [ 'title' => esc_html__( 'Page Elements', 'neve' ), 'priority' => 95, 'controls_to_wrap' => 2, 'expanded' => false, ], 'page_settings' => [ 'title' => esc_html__( 'Page', 'neve' ) . ' ' . esc_html__( 'Settings', 'neve' ), 'priority' => 106, 'controls_to_wrap' => 2, 'expanded' => false, ], 'meta' => [ 'title' => esc_html__( 'Post Meta', 'neve' ), 'priority' => 110, 'controls_to_wrap' => 5, 'expanded' => false, ], 'comments_section' => [ 'title' => esc_html__( 'Comments Section', 'neve' ), 'priority' => 150, 'expanded' => true, 'accordion' => false, 'active_callback' => function() { return $this->element_is_enabled( 'comments' ); }, ], 'comments_form' => [ 'title' => esc_html__( 'Submit Form Section', 'neve' ), 'priority' => 175, 'expanded' => true, 'accordion' => false, 'active_callback' => function() { return $this->element_is_enabled( 'comments' ); }, ], ]; foreach ( $headings as $heading_id => $heading_data ) { $this->add_control( new Control( 'neve_post_' . $heading_id . '_heading', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => $heading_data['title'], 'section' => $this->section, 'priority' => $heading_data['priority'], 'class' => $heading_id . '-accordion', 'expanded' => $heading_data['expanded'], 'accordion' => array_key_exists( 'accordion', $heading_data ) ? $heading_data['accordion'] : true, 'controls_to_wrap' => array_key_exists( 'controls_to_wrap', $heading_data ) ? $heading_data['controls_to_wrap'] : 0, 'active_callback' => array_key_exists( 'active_callback', $heading_data ) ? $heading_data['active_callback'] : '__return_true', ], 'Neve\Customizer\Controls\Heading' ) ); } } /** * Add header layout controls. */ private function header_layout() { $this->add_control( new Control( 'neve_post_cover_meta_before_title', [ 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => false, ], [ 'label' => esc_html__( 'Display meta before title', 'neve' ), 'section' => $this->section, 'type' => 'neve_toggle_control', 'priority' => 40, 'active_callback' => [ $this, 'is_cover_layout' ], ], 'Neve\Customizer\Controls\Checkbox' ) ); } /** * Add content order control. */ private function control_content_order() { $all_components = [ 'title-meta' => __( 'Title & Meta', 'neve' ), 'thumbnail' => __( 'Thumbnail', 'neve' ), 'content' => __( 'Content', 'neve' ), 'tags' => __( 'Tags', 'neve' ), 'post-navigation' => __( 'Post navigation', 'neve' ), 'comments' => __( 'Comments', 'neve' ), ]; if ( self::is_cover_layout() ) { $all_components = [ 'content' => __( 'Content', 'neve' ), 'tags' => __( 'Tags', 'neve' ), 'post-navigation' => __( 'Post navigation', 'neve' ), 'comments' => __( 'Comments', 'neve' ), ]; } $order_default_components = $this->post_ordering(); /** * Filters the elements on the single post page. * * @param array $all_components Single post page components. * * @since 2.11.4 */ $components = apply_filters( 'neve_single_post_elements', $all_components ); $this->add_control( new Control( 'neve_layout_single_post_elements_order', [ 'sanitize_callback' => [ $this, 'sanitize_post_elements_ordering' ], 'default' => wp_json_encode( $order_default_components ), ], [ 'label' => esc_html__( 'Elements Order', 'neve' ), 'section' => $this->section, 'components' => $components, 'priority' => 100, ], 'Neve\Customizer\Controls\React\Ordering' ) ); $this->add_control( new Control( 'neve_single_post_elements_spacing', [ 'sanitize_callback' => 'neve_sanitize_range_value', 'transport' => $this->selective_refresh, 'default' => '{"desktop":60,"tablet":60,"mobile":60}', ], [ 'label' => esc_html__( 'Spacing between elements', 'neve' ), 'section' => $this->section, 'type' => 'neve_responsive_range_control', 'input_attrs' => [ 'max' => 500, 'units' => [ 'px', 'em', 'rem' ], 'defaultVal' => [ 'mobile' => 60, 'tablet' => 60, 'desktop' => 60, 'suffix' => [ 'mobile' => 'px', 'tablet' => 'px', 'desktop' => 'px', ], ], ], 'priority' => 105, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'responsive' => true, 'vars' => '--spacing', 'selector' => '.nv-single-post-wrap', 'suffix' => 'px', ], ], ], '\Neve\Customizer\Controls\React\Responsive_Range' ) ); } /** * Add content spacing control. */ private function content_vspacing() { $this->add_control( new Control( Config::MODS_SINGLE_POST_VSPACING_INHERIT, [ 'sanitize_callback' => 'neve_sanitize_vspace_type', 'default' => 'inherit', ], [ 'label' => esc_html__( 'Content Vertical Spacing', 'neve' ), 'section' => $this->section, 'priority' => 107, 'choices' => [ 'inherit' => [ 'tooltip' => esc_html__( 'Inherit', 'neve' ), 'icon' => 'text', ], 'specific' => [ 'tooltip' => esc_html__( 'Custom', 'neve' ), 'icon' => 'text', ], ], 'footer_description' => [ 'inherit' => [ 'template' => esc_html__( 'Customize the default vertical spacing <ctaButton>here</ctaButton>.', 'neve' ), 'control_to_focus' => Config::MODS_CONTENT_VSPACING, ], ], ], '\Neve\Customizer\Controls\React\Radio_Buttons' ) ); $default_value = get_theme_mod( Config::MODS_CONTENT_VSPACING, $this->content_vspacing_default() ); $this->add_control( new Control( Config::MODS_SINGLE_POST_CONTENT_VSPACING, [ 'default' => $default_value, 'transport' => $this->selective_refresh, ], [ 'label' => __( 'Custom Value', 'neve' ), 'sanitize_callback' => [ $this, 'sanitize_spacing_array' ], 'section' => $this->section, 'input_attrs' => [ 'units' => [ 'px', 'vh' ], 'axis' => 'vertical', 'dependsOn' => [ Config::MODS_SINGLE_POST_VSPACING_INHERIT => 'specific' ], ], 'default' => $default_value, 'priority' => 107, 'live_refresh_selector' => true, 'live_refresh_css_prop' => [ 'cssVar' => [ 'vars' => '--c-vspace', 'selector' => 'body.single:not(.single-product) .neve-main', 'responsive' => true, 'fallback' => '', ], 'directional' => true, ], ], '\Neve\Customizer\Controls\React\Spacing' ) ); } /** * Add post meta controls. */ private function post_meta() { $components = apply_filters( 'neve_meta_filter', [ 'author' => __( 'Author', 'neve' ), 'category' => __( 'Category', 'neve' ), 'date' => __( 'Date', 'neve' ), 'comments' => __( 'Comments', 'neve' ), ] ); $default_value = get_theme_mod( 'neve_single_post_meta_fields', self::get_default_single_post_meta_fields() ); $this->add_control( new Control( 'neve_single_post_meta_fields', [ 'sanitize_callback' => 'neve_sanitize_meta_repeater', 'default' => $default_value, ], [ 'label' => esc_html__( 'Meta Order', 'neve' ), 'section' => $this->section, 'fields' => [ 'hide_on_mobile' => [ 'type' => 'checkbox', 'label' => __( 'Hide on mobile', 'neve' ), ], ], 'components' => $components, 'allow_new_fields' => 'no', 'priority' => 115, ], '\Neve\Customizer\Controls\React\Repeater' ) ); $default_separator = get_theme_mod( 'neve_metadata_separator', esc_html( '/' ) ); $this->add_control( new Control( 'neve_single_post_metadata_separator', [ 'sanitize_callback' => 'sanitize_text_field', 'default' => $default_separator, ], [ 'priority' => 120, 'section' => $this->section, 'label' => esc_html__( 'Separator', 'neve' ), 'description' => esc_html__( 'For special characters make sure to use Unicode. For example > can be displayed using \003E.', 'neve' ), 'type' => 'text', ] ) ); $author_avatar_default = get_theme_mod( 'neve_author_avatar', false ); $this->add_control( new Control( 'neve_single_post_author_avatar', [ 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => $author_avatar_default, ], [ 'label' => esc_html__( 'Show Author Avatar', 'neve' ), 'section' => $this->section, 'type' => 'neve_toggle_control', 'priority' => 125, ] ) ); $avatar_size_default = get_theme_mod( 'neve_author_avatar_size', '{ "mobile": 20, "tablet": 20, "desktop": 20 }' ); $this->add_control( new Control( 'neve_single_post_avatar_size', [ 'sanitize_callback' => 'neve_sanitize_range_value', 'default' => $avatar_size_default, ], [ 'label' => esc_html__( 'Avatar Size', 'neve' ), 'section' => $this->section, 'units' => [ 'px' ], 'input_attr' => [ 'mobile' => [ 'min' => 20, 'max' => 50, 'default' => 20, 'default_unit' => 'px', ], 'tablet' => [ 'min' => 20, 'max' => 50, 'default' => 20, 'default_unit' => 'px', ], 'desktop' => [ 'min' => 20, 'max' => 50, 'default' => 20, 'default_unit' => 'px', ], ], 'input_attrs' => [ 'min' => self::RELATIVE_CSS_UNIT_SUPPORTED_MIN_VALUE, 'max' => 50, 'defaultVal' => [ 'mobile' => 20, 'tablet' => 20, 'desktop' => 20, 'suffix' => [ 'mobile' => 'px', 'tablet' => 'px', 'desktop' => 'px', ], ], 'units' => [ 'px', 'em', 'rem' ], ], 'priority' => 130, 'active_callback' => function () { return get_theme_mod( 'neve_single_post_author_avatar', false ); }, 'responsive' => true, ], 'Neve\Customizer\Controls\React\Responsive_Range' ) ); $this->add_control( new Control( 'neve_single_post_show_last_updated_date', [ 'sanitize_callback' => 'neve_sanitize_checkbox', 'default' => get_theme_mod( 'neve_show_last_updated_date', false ), ], [ 'label' => esc_html__( 'Use last updated date instead of the published one', 'neve' ), 'section' => $this->section, 'type' => 'neve_toggle_control', 'priority' => 135, ] ) ); } /** * Add comments controls. */ private function comments() { $this->add_control( new Control( 'neve_post_comment_section_title', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'Section title', 'neve' ), 'description' => esc_html__( 'The following magic tags are available for this field: {title} and {comments_number}. Leave this field empty for default behavior.', 'neve' ), 'priority' => 155, 'section' => $this->section, 'type' => 'text', 'active_callback' => function() { return $this->element_is_enabled( 'comments' ); }, ] ) ); $this->add_boxed_layout_controls( 'comments', [ 'priority' => 160, 'section' => $this->section, 'padding_default' => $this->padding_default(), 'background_default' => 'var(--nv-light-bg)', 'color_default' => 'var(--nv-text-color)', 'boxed_selector' => '.nv-is-boxed.nv-comments-wrap', 'text_color_css_selector' => '.nv-comments-wrap.nv-is-boxed, .nv-comments-wrap.nv-is-boxed a', 'border_color_css_selector' => '.nv-comments-wrap.nv-is-boxed .nv-comment-article', 'toggle_active_callback' => function() { return $this->element_is_enabled( 'comments' ); }, 'active_callback' => function() { return $this->element_is_enabled( 'comments' ) && get_theme_mod( 'neve_comments_boxed_layout', false ); }, ] ); $this->add_control( new Control( 'neve_post_comment_form_title', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'Section title', 'neve' ), 'priority' => 180, 'section' => $this->section, 'type' => 'text', 'active_callback' => function() { return $this->element_is_enabled( 'comments' ); }, ] ) ); $this->add_control( new Control( 'neve_post_comment_form_button_style', [ 'default' => 'primary', 'sanitize_callback' => 'neve_sanitize_button_type', ], [ 'label' => esc_html__( 'Button style', 'neve' ), 'section' => $this->section, 'priority' => 185, 'type' => 'select', 'choices' => [ 'primary' => esc_html__( 'Primary', 'neve' ), 'secondary' => esc_html__( 'Secondary', 'neve' ), ], 'active_callback' => function() { return $this->element_is_enabled( 'comments' ); }, ] ) ); $this->add_control( new Control( 'neve_post_comment_form_button_text', [ 'sanitize_callback' => 'sanitize_text_field', ], [ 'label' => esc_html__( 'Button text', 'neve' ), 'priority' => 190, 'section' => $this->section, 'type' => 'text', 'active_callback' => function() { return $this->element_is_enabled( 'comments' ); }, ] ) ); $this->add_boxed_layout_controls( 'comments_form', [ 'priority' => 195, 'section' => $this->section, 'padding_default' => $this->padding_default(), 'is_boxed_default' => true, 'background_default' => 'var(--nv-light-bg)', 'color_default' => 'var(--nv-text-color)', 'boxed_selector' => '.nv-is-boxed.comment-respond', 'text_color_css_selector' => '.comment-respond.nv-is-boxed, .comment-respond.nv-is-boxed a', 'toggle_active_callback' => function() { return $this->element_is_enabled( 'comments' ); }, 'active_callback' => function() { return $this->element_is_enabled( 'comments' ) && get_theme_mod( 'neve_comments_form_boxed_layout', true ); }, ] ); } /** * Change heading controls properties. */ public function adjust_headings() { $this->change_customizer_object( 'control', 'neve_comments_heading', 'controls_to_wrap', 15 ); } /** * Active callback for sharing controls. * * @param string $element Post page element. * * @return bool */ public function element_is_enabled( $element ) { $default_order = apply_filters( 'neve_single_post_elements_default_order', array( 'title-meta', 'thumbnail', 'content', 'tags', 'comments', ) ); $content_order = get_theme_mod( 'neve_layout_single_post_elements_order', wp_json_encode( $default_order ) ); $content_order = json_decode( $content_order, true ); if ( ! in_array( $element, $content_order, true ) ) { return false; } return true; } /** * Sanitize content order control. */ public function sanitize_post_elements_ordering( $value ) { $allowed = [ 'thumbnail', 'title-meta', 'content', 'tags', 'post-navigation', 'comments', 'author-biography', 'related-posts', 'sharing-icons', ]; if ( empty( $value ) ) { return wp_json_encode( $allowed ); } $decoded = json_decode( $value, true ); foreach ( $decoded as $val ) { if ( ! in_array( $val, $allowed, true ) ) { return wp_json_encode( $allowed ); } } return $value; } /** * Fuction used for active_callback control property. * * @return bool */ public static function is_cover_layout() { return get_theme_mod( 'neve_post_header_layout' ) === 'cover'; } /** * Fuction used for active_callback control property for boxed title. * * @return bool */ public function is_boxed_title() { if ( ! self::is_cover_layout() ) { return false; } return get_theme_mod( 'neve_post_cover_title_boxed_layout', false ); } }
| ver. 1.4 |
Github
|
.
| PHP 5.4.45 | Generation time: 0 |
proxy
|
phpinfo
|
Settings