For the full copyright and license information, please view the LICENSE file that was distributed with this source code. --------------------------------------------------------------------- */ namespace CHV\Render; use G; use CHV; if (!defined('access') or !access) { die('This file cannot be directly accessed.'); } /* ---------------------------------------------------------------------------------------------------------------------------------------- */ /*** STRING DATA FUNCTIONS ***/ function get_email_body_str($file) { ob_start(); G\Render\include_theme_file($file); $mail_body = ob_get_contents(); ob_end_clean(); return $mail_body; } // For inline JS and CSS code from a given file function get_theme_inline_code($file, $type = null) { if (!isset($type)) { $type = pathinfo(rtrim($file, '.php'), PATHINFO_EXTENSION); } if (!CHV\getSetting('minify_enable') or !in_array($type, ['js', 'css'])) { G\Render\include_theme_file($file); } else { $ob_start = ob_start(); G\Render\include_theme_file($file); if ($ob_start) { $code = ob_get_clean(); ob_flush(); if ($code) { return get_cond_minified_code($code, $type); } } } } function show_theme_inline_code($file, $type = null) { G\Render\include_theme_file($file); // echo get_theme_inline_code($file, $type); // Don't minify this (saves execution time and is not needed) } /* ---------------------------------------------------------------------------------------------------------------------------------------- */ /*** THEME DATA FUNCTIONS ***/ function get_theme_file_url($file, $options = []) { $filepath = G_APP_PATH_THEME . $file; $filepath_override = G_APP_PATH_THEME . 'overrides/' . $file; if (file_exists($filepath_override)) { $filepath = $filepath_override; } return get_static_url($filepath, $options); } function get_static_url($filepath, $options = []) { $options = array_merge(['versionize' => true, 'minify' => null], $options); if ($options['minify'] !== false) { $filepath = get_cond_minified_file($filepath, $options['forced']); // Handle the conditional minify } $return = G\absolute_to_url($filepath, defined('CHV_ROOT_URL_STATIC') ? CHV_ROOT_URL_STATIC : null); if ($options['versionize']) { $return = versionize_src($return); } return $return; } function get_cond_minified_file($filepath, $forced = false) { // Check for theme override if (G\starts_with(G_APP_PATH_THEME, $filepath)) { $filepath_override = G\str_replace_first(G_APP_PATH_THEME, G_APP_PATH_THEME . 'overrides/', $filepath); if (file_exists($filepath_override)) { $filepath = $filepath_override; } } if (!CHV\getSetting('minify_enable')) { return $filepath; } return get_minified($filepath, ['forced' => $forced, 'output' => 'file']); } function get_cond_minified_code($code, $type = 'js') { if (!CHV\getSetting('minify_enable')) { return $code; } return get_minified($code, ['source_method' => 'inline', 'source_type' => $type, 'output' => 'inline']); } function get_minified($var, $options = []) { $options = array_merge(['source_method' => 'file', 'forced' => false], (array) $options); try { $minify = new G\Minify(array_merge($options, [ 'source' => $var, ])); $minify->exec(); $var = $minify->result; } catch (G\MinifyException $e) { error_log($e->getMessage()); } return $var; } function theme_file_exists($var) { return file_exists(G_APP_PATH_THEME . $var); } /* ---------------------------------------------------------------------------------------------------------------------------------------- */ /*** HTML TAGS ***/ function get_html_tags() { $classes = 'device-' . (G\Handler::getCond('mobile_device') ? 'mobile' : 'nonmobile') . ' tone-' . G\Handler::getVar('theme_tone') . ' top-bar-' . G\Handler::getVar('theme_top_bar_color') . ' unsafe-blur-' . (CHV\getSetting('theme_nsfw_blur') ? 'on' : 'off'); return get_lang_html_tags() . ' class="' . $classes . '"'; } /* ---------------------------------------------------------------------------------------------------------------------------------------- */ /*** LANGUAGE TAGS ***/ function get_lang_html_tags() { $lang = CHV\get_language_used(); return 'xml:lang="' . $lang['base'] . '" lang="' . $lang['base'] . '" dir="' . $lang['dir'] . '"'; } /* ---------------------------------------------------------------------------------------------------------------------------------------- */ /*** FORM ASSETS ***/ function get_select_options_html($arr, $selected) { $html = ''; foreach ($arr as $k => $v) { $selected = is_bool($selected) ? ($selected ? 1 : 0) : $selected; $html .= '' . "\n"; } return $html; } function get_checkbox_html($options = []) { if (!array_key_exists('name', $options)) { return 'ERR:CHECKBOX_NAME_MISSING'; } $options = array_merge([ 'value_checked' => 1, 'value_unchecked' => 0, 'label' => $options['name'], 'checked' => false, ], $options); $tooltip = $options['tooltip'] ? (' rel="tooltip" title="' . $options['tooltip'] . '"') : null; $html = '
' . $paragraph . '
', ]; if (is_array($error_msg)) { $html[] = '' . $solution . '
'; $html = join('', $html); $template = CHV_APP_PATH_CONTENT_SYSTEM . 'template.php'; if (!require_once($template)) { die("Can't find " . G\absolute_to_relative($template)); } die(); } function getFriendlyExif($Exif) { if (gettype($Exif) == 'string') { $Exif = json_decode($Exif); } if ($Exif->Make) { $exif_one_line = []; if ($Exif->ExposureTime) { $Exposure = $Exif->ExposureTime . 's'; $exif_one_line[] = $Exposure; } if ($Exif->FNumber or $Exif->COMPUTED->ApertureFNumber) { $Aperture = 'Æ’/' . ($Exif->FNumber ? G\fraction_to_decimal($Exif->FNumber) : explode('/', $Exif->COMPUTED->ApertureFNumber)[1]); $exif_one_line[] = $Aperture; } if ($Exif->ISOSpeedRatings) { $ISO = 'ISO' . (is_array($Exif->ISOSpeedRatings) ? $Exif->ISOSpeedRatings[0] : $Exif->ISOSpeedRatings); $exif_one_line[] = $ISO; } if ($Exif->FocalLength) { $FocalLength = G\fraction_to_decimal($Exif->FocalLength) . 'mm'; $exif_one_line[] = $FocalLength; } $exif_relevant = [ 'XResolution', 'YResolution', 'ResolutionUnit', 'ColorSpace', 'Orientation', 'Software', 'BrightnessValue', 'SensingMethod', 'SceneCaptureType', 'GainControl', 'ExposureBiasValue', 'MaxApertureValue', 'ExposureProgram', 'ExposureMode', 'MeteringMode', 'LightSource', 'Flash', 'WhiteBalance', 'DigitalZoomRatio', 'Contrast', 'Saturation', 'Sharpness', 'ExifVersion', 'DateTimeModified', 'DateTimeOriginal', 'DateTimeDigitized', ]; $ExifRelevant = []; foreach ($exif_relevant as $k) { if (property_exists($Exif, $k)) { $exifReadableValue = exifReadableValue($Exif, $k); if ($exifReadableValue !== null && !is_array($exifReadableValue)) { // Just make sure to avoid this array $ExifRelevant[$k] = $exifReadableValue; } } } $return = (object) [ 'Simple' => (object) [ 'Camera' => $Exif->Make . ' ' . $Exif->Model, 'Capture' => implode(' ', $exif_one_line), ], 'Full' => (object) array_merge([ 'Manufacturer' => $Exif->Make, 'Model' => $Exif->Model, 'ExposureTime' => $Exposure, 'Aperture' => $Aperture, 'ISO' => preg_replace('/iso/i', '', $ISO), 'FocalLength' => $FocalLength, ], $ExifRelevant), ]; // Clean all this stuff foreach ($return as $k => &$v) { if ($k == 'Full') { $v = (object) array_filter((array) $v, 'strlen'); } foreach ($v as $kk => $vv) { $return->{$k}->{$kk} = G\safe_html(strip_tags($vv)); } } return $return; } return null; } function exifReadableValue($Exif, $key) { $table = [ 'PhotometricInterpretation' => [ 0 => 'WhiteIsZero', 1 => 'BlackIsZero', 2 => 'RGB', 3 => 'RGB Palette', 4 => 'Transparency Mask', 5 => 'CMYK', 6 => 'YCbCr', 8 => 'CIELab', 9 => 'ICCLab', 10 => 'ITULab', 32803 => 'Color Filter Array', 32844 => 'Pixar LogL', 32845 => 'Pixar LogLuv', 34892 => 'Linear Raw', ], 'ColorSpace' => [ 1 => 'sRGB', 2 => 'Adobe RGB', 65533 => 'Wide Gamut RGB', 65534 => 'ICC Profile', 65535 => 'Uncalibrated', ], 'Orientation' => [ 1 => 'Horizontal (normal)', 2 => 'Mirror horizontal', 3 => 'Rotate 180', 4 => 'Mirror vertical', 5 => 'Mirror horizontal and rotate 270 CW', 6 => 'Rotate 90 CW', 7 => 'Mirror horizontal and rotate 90 CW', 8 => 'Rotate 270 CW', ], 'ResolutionUnit' => [ 1 => 'None', 2 => 'inches', 3 => 'cm', ], 'ExposureProgram' => [ 0 => 'Not Defined', 1 => 'Manual', 2 => 'Program AE', 3 => 'Aperture-priority AE', 4 => 'Shutter speed priority AE', 5 => 'Creative (Slow speed)', 6 => 'Action (High speed)', 7 => 'Portrait', 8 => 'Landscape', 9 => 'Bulb', ], 'MeteringMode' => [ 0 => 'Unknown', 1 => 'Average', 2 => 'Center-weighted average', 3 => 'Spot', 4 => 'Multi-spot', 5 => 'Multi-segment', 6 => 'Partial', 255 => 'Other', ], 'ExposureMode' => [ 0 => 'Auto', 1 => 'Manual', 2 => 'Auto bracket', ], 'SensingMethod' => [ 1 => 'Monochrome area', 2 => 'One-chip color area', 3 => 'Two-chip color area', 4 => 'Three-chip color area', 5 => 'Color sequential area', 6 => 'Monochrome linear', 7 => 'Trilinear', 8 => 'Color sequential linear', ], 'SceneCaptureType' => [ 0 => 'Standard', 1 => 'Landscape', 2 => 'Portrait', 3 => 'Night', ], 'GainControl' => [ 0 => 'None', 1 => 'Low gain up', 2 => 'High gain up', 3 => 'Low gain down', 4 => 'High gain down', ], 'Saturation' => [ 0 => 'Normal', 1 => 'Low', 2 => 'High', ], 'Sharpness' => [ 0 => 'Normal', 1 => 'Soft', 2 => 'Hard', ], 'Flash' => [ 0 => 'No Flash', 1 => 'Fired', 5 => 'Fired, Return not detected', 7 => 'Fired, Return detected', 8 => 'On, Did not fire', 9 => 'On, Fired', 13 => 'On, Return not detected', 15 => 'On, Return detected', 16 => 'Off, Did not fire', 20 => 'Off, Did not fire, Return not detected', 24 => 'Auto, Did not fire', 25 => 'Auto, Fired', 29 => 'Auto, Fired, Return not detected', 31 => 'Auto, Fired, Return detected', 32 => 'No flash function', 48 => 'Off, No flash function', 65 => 'Fired, Red-eye reduction', 69 => 'Fired, Red-eye reduction, Return not detected', 71 => 'Fired, Red-eye reduction, Return detected', 73 => 'On, Red-eye reduction', 77 => 'On, Red-eye reduction, Return not detected', 79 => 'On, Red-eye reduction, Return detected', 80 => 'Off, Red-eye reduction', 88 => 'Auto, Did not fire, Red-eye reduction', 89 => 'Auto, Fired, Red-eye reduction', 93 => 'Auto, Fired, Red-eye reduction, Return not detected', 95 => 'Auto, Fired, Red-eye reduction, Return detected', ], 'LightSource' => [ 0 => 'Unknown', 1 => 'Daylight', 2 => 'Fluorescent', 3 => 'Tungsten (Incandescent)', 4 => 'Flash', 9 => 'Fine Weather', 10 => 'Cloudy', 11 => 'Shade', 12 => 'Daylight Fluorescent', 13 => 'Day White Fluorescent', 14 => 'Cool White Fluorescent', 15 => 'White Fluorescent', 16 => 'Warm White Fluorescent', 17 => 'Standard Light A', 18 => 'Standard Light B', 19 => 'Standard Light C', 20 => 'D55', 21 => 'D65', 22 => 'D75', 23 => 'D50', 24 => 'ISO Studio Tungsten', 255 => 'Other', ], ]; $table['Contrast'] = $table['Saturation']; if (is_object($Exif) and is_array($Exif->$key)) { $value_arr = []; foreach ($Exif->$key as $k) { $value_arr[] = $table[$key][$k]; } $value = implode(', ', $value_arr); } else { // Set $value from table above (translator) if exists $value = $table[$key][$Exif->$key] ?: $Exif->$key; } switch ($key) { case 'DateTime': case 'DateTimeOriginal': case 'DateTimeDigitized': case 'DateTimeModified': $value = $value !== null ? preg_replace('/(\d{4})(:)(\d{2})(:)(\d{2})/', '$1-$3-$5', $value) : null; break; case 'WhiteBalance': $value = $value == 0 ? 'Auto' : $value; break; case 'BrightnessValue': case 'MaxApertureValue': $value = $value ? G\fraction_to_decimal($value) : null; break; case 'XResolution': case 'YResolution': $value = $value ? (floor(G\fraction_to_decimal($value)) . ' dpi') : null; break; } return $value ?: null; } function arr_printer($arr, $tpl = '', $wrap = []) { ksort($arr); $rtn = ''; $rtn .= $wrap[0]; foreach ($arr as $k => $v) { if (is_array($v)) { $rtn .= strtr($tpl, ['%K' => $k, '%V' => arr_printer($v, $tpl, $wrap)]); } else { $rtn .= strtr($tpl, ['%K' => $k, '%V' => $v]); } } $rtn .= $wrap[1]; return $rtn; } function versionize_src($src) { return $src . '?' . md5(CHV\get_chevereto_version()); } function show_banner($banner, $sfw = true) { if (!$sfw) { $banner .= '_nsfw'; } $banner_code = CHV\get_banner_code($banner, false); if ($banner_code) { echo ' '; } } function getPixel($type) { if (!in_array($type, ['queue', 'ping'])) { return; } return ''; } function showQueuePixel() { if (!defined('G_APP_GITHUB_REPO')) { return; } if (version_compare(CHV\getSetting('chevereto_version_installed'), '3.5.5', '<')) { return; } if (CHV\DB::queryFetchSingle('SELECT EXISTS(SELECT 1 FROM ' . CHV\DB::getTable('queues') . ' WHERE queue_status = "pending") as has')['has'] == 0) { return; } echo getPixel('queue'); } function show_queue_img() { return showQueuePixel(); } function showPingPixel() { if (CHV\getSetting('enable_automatic_updates_check') && (is_null(CHV\getSetting('update_check_datetimegmt')) || G\datetime_add(CHV\getSetting('update_check_datetimegmt'), 'P1D') < G\datetimegmt())) { echo getPixel('ping'); } } function displayEmptyPixel() { header('Content-Type: image/gif'); header('Content-Length: 43'); echo base64_decode('R0lGODlhAQABAIAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='); die(); } function showComments() { switch (CHV\getSetting('comments_api')) { case 'js': $html = CHV\getSetting('comment_code'); break; case 'disqus': $disqus_secret = CHV\getSetting('disqus_secret_key'); $disqus_public = CHV\getSetting('disqus_public_key'); if (!empty($disqus_secret) && !empty($disqus_public)) { $logged_user = CHV\Login::getuser(); $data = [ 'id' => $logged_user['id_encoded'], 'username' => $logged_user['name'], 'email' => $logged_user['email'], 'avatar' => $logged_user['avatar']['url'], 'url' => $logged_user['url'], ]; function dsq_hmacsha1($data, $key) { $blocksize = 64; $hashfunc = 'sha1'; if (strlen($key) > $blocksize) { $key = pack('H*', $hashfunc($key)); } $key = str_pad($key, $blocksize, chr(0x00)); $ipad = str_repeat(chr(0x36), $blocksize); $opad = str_repeat(chr(0x5c), $blocksize); $hmac = pack('H*', $hashfunc(($key ^ $opad) . pack('H*', $hashfunc(($key ^ $ipad) . $data)))); return bin2hex($hmac); } $message = base64_encode(json_encode($data)); $timestamp = time(); $hmac = dsq_hmacsha1($message . ' ' . $timestamp, $disqus_secret); $auth = $message . ' ' . $hmac . ' ' . $timestamp; } $html = strtr(' ', [ '%page_url' => G\get_current_url(), '%page_id' => G\str_replace_first(G\get_route_path(), G\get_route_name(), G\get_route_path(true)), // image.ID '%shortname' => CHV\getSetting('disqus_shortname'), '%language_code' => CHV\get_language_used()['base'], '%auth' => isset($auth) ? $auth : null, '%api_key' => $disqus_public, ]); break; } echo $html; }