<?php
/*
!
* Jetpack CRM
* https://jetpackcrm.com
* V2.0.6
*
* Copyright 2020 Automattic
*
* Date: 24/05/2017
*/
/*
======================================================
Breaking Checks ( stops direct access )
====================================================== */
if ( ! defined( 'ZEROBSCRM_PATH' ) ) {
exit( 0 );
}
/*
======================================================
/ Breaking Checks
====================================================== */
// Globals...
// } Cache of locale... if set (avoids multiple getting for each label)
global $zeroBSCRM_locale;
/*
this isn't used!
// } Temp mapping for 2.0.6:
global $zeroBSCRM_localisationTextOverrides; $zeroBSCRM_localisationTextOverrides = array(
'en-US' => array(
array('County','State'),
array('Postcode','Zip Code'),
array('Mobile Telephone','Cell')
)
); */
/*
This func was built to centralise "workarounds" where the default
WP date config conflicted with that of the jquery datepicker used.
... WH did so 27/2/19
... ultimately this method is clearly flawed somewhere in the linkage though,
... as these keep cropping up.
*/
function zeroBSCRM_locale_wpConversionWorkarounds( $format = 'd/m/Y' ) {
// allow for this funky thing here. (only if getting default format)
if ( $format == 'F j, Y' ) {
$format = 'm/d/Y';
}
if ( $format == 'jS F Y' ) {
$format = 'd/m/Y';
}
if ( $format == 'j F, Y' ) {
$format = 'd/m/Y';
}
// added 27/2/19 JIRA-BS-792
if ( $format == 'j. F Y' ) {
$format = 'd/m/Y';
}
if ( $format == 'j F Y' ) {
$format = 'd/m/Y';
}
// added 11/03/19 JIRA-ZBS-817
if ( $format == 'F j, Y' ) {
$format = 'm/d/Y';
}
// Temporary workaround for gh-273, to be addressed in full under gh-313
if ( $format === 'Y. F j.' ) {
$format = 'Y/d/m';
}
return $format;
}
// https://codex.wordpress.org/Function_Reference/date_i18n
function zeroBSCRM_locale_utsToDate( $unixTimestamp = -1 ) {
if ( $unixTimestamp === -1 ) {
$unixTimestamp = time();
}
// return date_i18n( get_option( 'date_format' ), $unixTimestamp );
return zeroBSCRM_date_i18n( get_option( 'date_format' ), $unixTimestamp );
}
// https://codex.wordpress.org/Function_Reference/date_i18n + 'Y-m-d H:i:s'
function zeroBSCRM_locale_utsToDatetime( $unixTimestamp = -1 ) {
if ( $unixTimestamp === -1 ) {
$unixTimestamp = time();
}
// return date_i18n( 'Y-m-d H:i:s', $unixTimestamp );
return zeroBSCRM_date_i18n( 'Y-m-d H:i:s', $unixTimestamp );
}
// same as above but in WP chosen formats
function zeroBSCRM_locale_utsToDatetimeWP( $unixTimestamp = -1 ) {
if ( $unixTimestamp === -1 ) {
$unixTimestamp = time();
}
// return date_i18n( 'Y-m-d H:i:s', $unixTimestamp );
return zeroBSCRM_date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $unixTimestamp );
}
// adapted from https://stackoverflow.com/questions/2891937/strtotime-doesnt-work-with-dd-mm-yyyy-format
function zeroBSCRM_locale_dateToUTS( $dateInFormat = '', $withTime = false, $specificFormat = false ) {
try {
$format = zeroBSCRM_date_defaultFormat();
if ( $withTime ) {
$format .= ' H:i';
// hacky catch of AM/PM + add to format end...?
if ( str_contains( $dateInFormat, 'AM' ) || str_contains( $dateInFormat, 'PM' ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
$format .= ' A';
}
}
// if specificFormat, use that
if ( $specificFormat !== false ) {
$format = $specificFormat;
}
// debug echo 'from: '.$dateInFormat.' in format '.$format.':';
// requires php 5.3+
$dt = DateTime::createFromFormat( '!' . $format, $dateInFormat );
// debug echo 'DT Errors:<pre>'.print_r(DateTime::getLastErrors(),1).'</pre>';
/*
can use this to check for errors:
print_r(DateTime::getLastErrors());
e.g.
Array
(
[warning_count] => 0
[warnings] => Array
(
)
[error_count] => 4
[errors] => Array
(
[2] => Unexpected data found.
[5] => Unexpected data found.
)
) */
// if was failed conversion, is set to false
// if ($dt !== false)
if ( $dt instanceof DateTime ) {
return $dt->getTimestamp();
} else {
// this only happens when people have $date in one format, but their settings match a diff setting
// try this
$dt = strtotime( $dateInFormat );
// debug
// echo 'from: '.$dateInFormat.' in format '.$format.'... = '.$dt;
if ( $dt !== false && $dt > 0 ) {
return $dt;
}
return false;
}
} catch ( Exception $e ) {
// debug echo 'error:'.$e->getMessage();
try {
// try this
$dt = strtotime( $dateInFormat );
// echo 'dt:'.$dateInFormat.'=>'; print_r($dt); echo '!';
if ( $dt !== false && $dt > 0 ) {
return $dt;
}
} catch ( Exception $e ) {
// really not a great date...
// echo 'error2:'.$e->getMessage();
}
}
return false;
}
/*
WH switched this for the above zeroBSCRM_locale_dateToUTS, which is just the next answer down on your original stack overflow link
... this was good, but that was a little more cleaner/all-encompassing.
// function to convert date to time for ZBS use (since multile dates used) this was a bit of a pig
// since when updating DB it needs Y-m-d H:i:s format. and strtotime does not work with UK date formats
// hence the 1 Jan 1970 bug reported in the date picker from Paul (groove-85858971)
function zeroBSCRM_strtotime($date = ''){
$the_format = get_option( 'date_format' );
if($the_format == 'd/m/Y' || $the_format = 'jS F Y' || $the_format = 'F j, Y'){
$date = str_replace('/', '-', $date);
}
$unixtime = strtotime($date);
return $unixtime;
} */
// wh added 9/8/18 - adds time to zeroBSCRM_date_i18n, basically
// ... just appends H:i to format
// ... had to use for .zbs-date-time datepicker
function zeroBSCRM_date_i18n_plusTime( $format, $timestamp, $isUTC = false ) {
// pass -1 to default to WP date
if ( $format == -1 ) {
$format = zeroBSCRM_date_defaultFormat();
}
// add time
$format .= ' H:i';
return zeroBSCRM_date_i18n( $format, $timestamp, false, $isUTC );
}
// this is a modified version of 2x answer here, takinginto account +- gmt_offset
// https://wordpress.stackexchange.com/questions/94755/converting-timestamps-to-local-time-with-date-l18n
// fully testing + works as at 11/05/18
// WH: As of 16/8/18 - has extra var $isUTC -
// this is a workaround for those peeps in non UTC
// who, when converting dates, were getting back 'offset' dates (this is because we're using timestamps of midnight here)
function zeroBSCRM_date_i18n( $format, $timestamp, $notused = true, $isUTC = false ) {
// catch empty timestamps
if ( ! is_numeric( $timestamp ) ) {
$timestamp = time();
}
// pass -1 to default to WP date
if ( $format == -1 ) {
$format = zeroBSCRM_date_defaultFormat();
}
// Timezone Support
// Default:
$timezone_str = 'UTC';
// got a non-utc timestamp str?
if ( ! $isUTC ) {
$timezone_str = get_option( 'timezone_string' );
if ( empty( $timezone_str ) ) {
// if offset, use that
$offsetStr = get_option( 'gmt_offset' );
if ( ! empty( $offsetStr ) ) {
$offset = $offsetStr * HOUR_IN_SECONDS;
return date_i18n( $format, $timestamp + $offset, true );
}
}
}
// if still no return, default:
if ( empty( $timezone_str ) ) {
$timezone_str = 'UTC';
}
// proceed with timezone str:
$timezone = new \DateTimeZone( $timezone_str );
// The date in the local timezone.
$date = new \DateTime( 'now', $timezone );
$date->setTimestamp( $timestamp );
$date_str = $date->format( 'Y-m-d H:i:s' );
// Pretend the local date is UTC to get the timestamp
// to pass to date_i18n().
$utc_timezone = new \DateTimeZone( 'UTC' );
$utc_date = new \DateTime( $date_str, $utc_timezone );
$timestamp = $utc_date->getTimestamp();
return date_i18n( $format, $timestamp, true );
}
// gets format + returns format (with some mods)
function zeroBSCRM_date_defaultFormat() {
$format = get_option( 'date_format' );
// catch specific issues
$format = zeroBSCRM_locale_wpConversionWorkarounds( $format );
return $format;
}
// https://stackoverflow.com/questions/16702398/convert-a-php-date-format-to-a-jqueryui-datepicker-date-format
// further down
// We need this to take WP locale -> datetimepicker
// Note: WH added strtoupper, seems to be req. for datetimerangepicker
/*
* Matches each symbol of PHP date format standard
* with jQuery equivalent codeword
* @author Tristan Jahier
*/
function zeroBSCRM_date_PHPtoDatePicker( $format ) {
// dd M yy
static $assoc = array(
'Y' => 'yyyy',
'y' => 'yy',
'F' => 'MM',
'm' => 'mm',
'l' => 'DD',
'd' => 'dd',
'D' => 'D',
'j' => 'd',
'M' => 'M',
'n' => 'm',
'z' => 'o',
'N' => '',
'S' => 'd',
'w' => '',
'W' => '',
't' => '',
'L' => '',
'o' => '',
'a' => '',
'A' => '',
'B' => '',
'g' => '',
'G' => '',
'h' => '',
'H' => '',
'i' => '',
's' => '',
'u' => '',
);
$keys = array_keys( $assoc );
$indeces = array_map(
function ( $index ) {
return '{{' . $index . '}}';
},
array_keys( $keys )
);
$format = str_replace( $keys, $indeces, $format );
// Note: WH added strtoupper, seems to be req. for datetimerangepicker
return strtoupper( str_replace( $indeces, $assoc, $format ) );
}
function zeroBSCRM_date_localeForDaterangePicker() {
$dateTimePickerFormat = 'DD.MM.YYYY';
$wpDateFormat = get_option( 'date_format' );
if ( ! empty( $wpDateFormat ) ) {
// catch specific issues
$wpDateFormat = zeroBSCRM_locale_wpConversionWorkarounds( $wpDateFormat );
$dateTimePickerFormat = zeroBSCRM_date_PHPtoDatePicker( $wpDateFormat );
}
return array(
'format' => $dateTimePickerFormat,
'applyLabel' => __( 'Apply', 'zero-bs-crm' ),
'cancelLabel' => __( 'Clear', 'zero-bs-crm' ),
'fromLabel' => __( 'From', 'zero-bs-crm' ),
'toLabel' => __( 'To', 'zero-bs-crm' ),
'customRangeLabel' => __( 'Custom', 'zero-bs-crm' ),
'separator' => ' - ',
'daysOfWeek' => array(
__( 'Su', 'zero-bs-crm' ),
__( 'Mo', 'zero-bs-crm' ),
__( 'Tu', 'zero-bs-crm' ),
__( 'We', 'zero-bs-crm' ),
__( 'Th', 'zero-bs-crm' ),
__( 'Fr', 'zero-bs-crm' ),
__( 'Sa', 'zero-bs-crm' ),
),
'monthNames' => array(
__( 'January', 'zero-bs-crm' ),
__( 'February', 'zero-bs-crm' ),
__( 'March', 'zero-bs-crm' ),
__( 'April', 'zero-bs-crm' ),
__( 'May', 'zero-bs-crm' ),
__( 'June', 'zero-bs-crm' ),
__( 'July', 'zero-bs-crm' ),
__( 'August', 'zero-bs-crm' ),
__( 'September', 'zero-bs-crm' ),
__( 'October', 'zero-bs-crm' ),
__( 'November', 'zero-bs-crm' ),
__( 'December', 'zero-bs-crm' ),
),
'firstDay' => (int) get_option( 'start_of_week', 0 ),
);
/*
full possible settings
"format": "MM/DD/YYYY",
"separator": " - ",
"applyLabel": "Apply",
"cancelLabel": "Cancel",
"fromLabel": "From",
"toLabel": "To",
"customRangeLabel": "Custom",
"daysOfWeek": [
"Su",
"Mo",
"Tu",
"We",
"Th",
"Fr",
"Sa"
],
"monthNames": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
"firstDay": 1
*/
}
/*
Removed 2.14 - opting for _e :)
// } This simply dumps any 'overrides' into the __w function before returning (E.g. County -> State)
function zeroBSCRM_localiseFieldLabel($labelStr=''){
global $zeroBSCRM_localisationTextOverrides;
$locale = zeroBSCRM_getLocale();
#} Init just checks if set to en_US
if (isset($locale) && !empty($locale) && isset($zeroBSCRM_localisationTextOverrides[$locale])){
#} locale present - replace any?
$replacement = $labelStr;
foreach ($zeroBSCRM_localisationTextOverrides[$locale] as $repArr){
if (isset($repArr[0]) && $repArr[0] == $labelStr) $replacement = $repArr[1];
}
#} Return replacement or orig..
return $replacement;
}
return $labelStr;
} */
// for JS there's a ver of this in admin.global called zeroBSCRMJS_formatCurrency
function zeroBSCRM_formatCurrency( $amount ) {
// see here: https://akrabat.com/using-phps-numberformatter-to-format-currencies/
// needs the international PHP extension (hence wrapped in if exists)
/*
You can check if you have the intl extension installed using php -m | grep intl and if you don't then you can install it with apt-get install php5-intl or yum install php-intl assuming you use your distro's stock PHP. (If you compile your own, then --enable-intl is the switch you need.)
*/
global $zbs;
/*
'currency' => symbol
'currency_position' => 0,
'currency_format_thousand_separator' => ',',
'currency_format_decimal_separator' => '.',
'currency_format_number_of_decimals' => 2,
*/
// WH would be nice if we could get a GROUP of settings (i.e. just the ones above.. )
$settings = $zbs->settings->getAll();
// defaults declared elsewhere so do I need the below :declare: :bear:
$zbscrm_currency_symbol = '$';
$zbscrm_currency_format_thousand_separator = ',';
$zbscrm_currency_format_decimal_separator = '.';
$zbscrm_currency_format_number_of_decimals = 2;
$zbscrm_currency_symbol = zeroBSCRM_getCurrencyChr();
$zbscrm_currency_position = $settings['currency_position'];
$zbscrm_currency_format_thousand_separator = $settings['currency_format_thousand_separator'];
$zbscrm_currency_format_decimal_separator = $settings['currency_format_decimal_separator'];
$zbscrm_currency_format_number_of_decimals = $settings['currency_format_number_of_decimals'];
// process the number
$formatted_number = number_format(
(float) $amount,
$zbscrm_currency_format_number_of_decimals,
$zbscrm_currency_format_decimal_separator,
$zbscrm_currency_format_thousand_separator
);
// add the currecy symbol
switch ( $zbscrm_currency_position ) {
case 0: // left
$formatted_amount = $zbscrm_currency_symbol . $formatted_number;
break;
case 1: // right
$formatted_amount = $formatted_number . $zbscrm_currency_symbol;
break;
case 2: // left with space
$formatted_amount = $zbscrm_currency_symbol . ' ' . $formatted_number;
break;
case 3: // right with space
$formatted_amount = $formatted_number . ' ' . $zbscrm_currency_symbol;
break;
default: // default to the left
$formatted_amount = $zbscrm_currency_symbol . $formatted_number;
break;
}
return $formatted_amount;
/*
AS OF v2.84+ we shunt everything through the settings rather than the below which seems unreliable
$locale = zeroBSCRM_getLocale(true);
if(class_exists('NumberFormatter')){
$formatter = new NumberFormatter($locale, NumberFormatter::CURRENCY);
return $formatter->formatCurrency($amount, zeroBSCRM_getCurrencyStr());
}
else{
// use wp default /// which needs this currency :)
return zeroBSCRM_getCurrencyChr().number_format_i18n($amount);
}
*/
}
function zeroBSCRM_format_quantity( $quantity ) {
return sprintf( '%g', $quantity );
}
function zeroBSCRM_getLocale( $full = true ) {
// phpcs:disable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
global $zeroBSCRM_locale;
if ( ! isset( $zeroBSCRM_locale ) ) {
$zeroBSCRM_locale = get_bloginfo( 'language' );
}
if ( ! $full ) {
$zeroBSCRM_locale_short = str_replace( '_', '-', $zeroBSCRM_locale ); // just in case en_GB?
$zeroBSCRM_locale_short = explode( '-', $zeroBSCRM_locale_short )[0];
return $zeroBSCRM_locale_short;
}
return $zeroBSCRM_locale;
// phpcs:enable WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
}
// getLocale wrapper
function zeroBSCRM_locale_getServerLocale() {
// https://stackoverflow.com/questions/29932843/php-get-current-locale
// limited use, e.g. flywheel returns 'C'
return setlocale( LC_ALL, 0 );
}
/*
===========================================
Helper functions (moved from dal 2.2)
=========================================== */
// } Minified get currency func
function zeroBSCRM_getCurrencyChr() {
// } Curr
$theCurrency = zeroBSCRM_getSetting( 'currency' );
$theCurrencyChar = '£';
if ( isset( $theCurrency ) && isset( $theCurrency['chr'] ) ) {
$theCurrencyChar = $theCurrency['chr'];
}
return $theCurrencyChar;
}
function zeroBSCRM_getCurrencyStr() {
// } Curr
$theCurrency = zeroBSCRM_getSetting( 'currency' );
$theCurrencyStr = 'GBP';
if ( isset( $theCurrency ) && isset( $theCurrency['chr'] ) ) {
$theCurrencyStr = $theCurrency['strval'];
}
return $theCurrencyStr;
}
function zeroBSCRM_getTimezoneOffset() {
return get_option( 'gmt_offset' );
}
function zeroBSCRM_getCurrentTime() {
return current_time();
}
// } Date time formats
// http://wordpress.stackexchange.com/questions/591/how-to-get-the-date-format-and-time-format-settings-for-use-in-my-template
function zeroBSCRM_getDateFormat() {
// } cache
global $zeroBSCRM_dateFormat;
if ( isset( $zeroBSCRM_dateFormat ) ) {
return $zeroBSCRM_dateFormat;
}
$zeroBSCRM_dateFormat = get_option( 'date_format' );
return $zeroBSCRM_dateFormat;
}
function zeroBSCRM_getTimeFormat() {
// } cache
global $zeroBSCRM_timeFormat;
if ( isset( $zeroBSCRM_timeFormat ) ) {
return $zeroBSCRM_timeFormat;
}
$zeroBSCRM_timeFormat = get_option( 'time_format' );
return $zeroBSCRM_timeFormat;
}
// output locale stuff into header :)
// actually left in main .php for now