// reset any static caching
self::$_cache = NULL;
- // reset any db caching
- $config = CRM_Core_Config::singleton();
- $smartGroupCacheTimeout = CRM_Contact_BAO_GroupContactCache::smartGroupCacheTimeout();
-
- //make sure to give original timezone settings again.
- $now = CRM_Utils_Date::getUTCTime();
-
$query = "
DELETE
FROM civicrm_acl_cache
WHERE modified_date IS NULL
- OR (TIMESTAMPDIFF(MINUTE, modified_date, $now) >= $smartGroupCacheTimeout)
+ OR (modified_date <= %1)
";
- CRM_Core_DAO::singleValueQuery($query);
+ $params = array(1 => array(CRM_Contact_BAO_GroupContactCache::getCacheInvalidDateTime(), 'String'));
+ CRM_Core_DAO::singleValueQuery($query, $params);
// CRM_Core_DAO::singleValueQuery("TRUNCATE TABLE civicrm_acl_contact_cache"); // No, force-commits transaction
// CRM_Core_DAO::singleValueQuery("DELETE FROM civicrm_acl_contact_cache"); // Transaction-safe
* the sql query which lists the groups that need to be refreshed
*/
public static function groupRefreshedClause($groupIDClause = NULL, $includeHiddenGroups = FALSE) {
- $smartGroupCacheTimeout = self::smartGroupCacheTimeout();
- $now = CRM_Utils_Date::getUTCTime();
+ $smartGroupCacheTimeoutDateTime = self::getCacheInvalidDateTime();
$query = "
SELECT g.id
FROM civicrm_group g
WHERE ( g.saved_search_id IS NOT NULL OR g.children IS NOT NULL )
AND g.is_active = 1
-AND ( g.cache_date IS NULL OR
- ( TIMESTAMPDIFF(MINUTE, g.cache_date, $now) >= $smartGroupCacheTimeout ) OR
- ( $now >= g.refresh_date )
- )
-";
+AND (
+ g.cache_date IS NULL
+ OR cache_date <= $smartGroupCacheTimeoutDateTime
+ OR NOW() >= g.refresh_date
+)";
if (!$includeHiddenGroups) {
$query .= "AND (g.is_hidden = 0 OR g.is_hidden IS NULL)";
if (!empty($refreshGroupIDs)) {
$refreshGroupIDString = CRM_Core_DAO::escapeString(implode(', ', $refreshGroupIDs));
- $time = CRM_Utils_Date::getUTCTime(self::smartGroupCacheTimeout() * 60);
+ $time = self::getRefreshDateTime();
$query = "
UPDATE civicrm_group g
SET g.refresh_date = $time
// only update cache entry if we had any values
if ($processed) {
// also update the group with cache date information
- //make sure to give original timezone settings again.
- $now = CRM_Utils_Date::getUTCTime();
+ $now = date('YmdHis');
$refresh = 'null';
}
else {
static $invoked = FALSE;
// typically this needs to happy only once per instance
- // this is especially TRUE in import, where we dont need
+ // this is especially TRUE in import, where we don't need
// to do this all the time
// this optimization is done only when no groupID is passed
// i.e. cache is reset for all groups
}
$refresh = NULL;
- $params = array();
$smartGroupCacheTimeout = self::smartGroupCacheTimeout();
+
$now = CRM_Utils_Date::getUTCTime();
$refreshTime = CRM_Utils_Date::getUTCTime($smartGroupCacheTimeout * 60);
// HACK: Hardcoded delete limit.
$deleteLimit = 1000;
+ $params = array(
+ 1 => array(self::getCacheInvalidDateTime(), 'String'),
+ 2 => array(self::getRefreshDateTime(), 'String'),
+ );
+
+
if (!isset($groupID)) {
if ($smartGroupCacheTimeout == 0) {
$query = "
";
$refresh = "
UPDATE civicrm_group g
-SET refresh_date = $refreshTime
-WHERE g.cache_date > %1
+SET refresh_date = %2
+WHERE g.cache_date < %1
AND refresh_date IS NULL
";
- $cacheTime = date('Y-m-d H-i-s', strtotime("- $smartGroupCacheTimeout minutes"));
- $params = array(1 => array($cacheTime, 'String'));
}
}
elseif (is_array($groupID)) {
return;
}
- // grab a lock so other processes dont compete and do the same query
+ // grab a lock so other processes don't compete and do the same query
$lock = Civi\Core\Container::singleton()->get('lockManager')->acquire("data.core.group.{$groupID}");
if (!$lock->isAcquired()) {
- // this can cause inconsistent results since we dont know if the other process
+ // this can cause inconsistent results since we don't know if the other process
// will fill up the cache before our calling routine needs it.
// however this routine does not return the status either, so basically
// its a "lets return and hope for the best"
}
}
+ /**
+ * Get the datetime from which the cache should be considered invalid.
+ *
+ * Ie if the smartgroup cache timeout is 5 minutes ago then the cache is invalid if it was
+ * refreshed 6 minutes ago, but not if it was refreshed 4 minutes ago.
+ *
+ * @return string
+ */
+ public static function getCacheInvalidDateTime() {
+ return date('Ymdhis', strtotime("-" . self::smartGroupCacheTimeout() . " Minutes"));
+ }
+
+ /**
+ * Get the date when the cache should be refreshed from.
+ *
+ * Ie. now + the offset & we will delete anything prior to then.
+ *
+ * @return string
+ */
+ public static function getRefreshDateTime() {
+ return date('Ymdhis', strtotime("+ " . self::smartGroupCacheTimeout() . " Minutes"));
+ }
+
}
* list(string $orderByClause, string $additionalFromClause).
*/
protected function prepareOrderBy($sort, $sortByChar, $sortOrder, $additionalFromClause) {
+ $order = NULL;
$config = CRM_Core_Config::singleton();
if ($config->includeOrderByClause ||
isset($this->_distinctComponentClause)
if (empty($params['contact_type'])) {
$params['contact_type'] = 'Individual';
}
- $customFields = CRM_Core_BAO_CustomField::getFields($params['contact_type'], FALSE, FALSE, $csType);
+
+ // get array of subtypes - CRM-18708
+ if (in_array($csType, array('Individual', 'Organization', 'Household'))) {
+ $csType = self::getSubtypes($params['contact_type']);
+ }
+
+ if (is_array($csType)) {
+ // fetch custom fields for every subtype and add it to $customFields array
+ // CRM-18708
+ $customFields = array();
+ foreach ($csType as $cType) {
+ $customFields += CRM_Core_BAO_CustomField::getFields($params['contact_type'], FALSE, FALSE, $cType);
+ }
+ }
+ else {
+ $customFields = CRM_Core_BAO_CustomField::getFields($params['contact_type'], FALSE, FALSE, $csType);
+ }
$addressCustomFields = CRM_Core_BAO_CustomField::getFields('Address');
$customFields = $customFields + $addressCustomFields;
return $allowToCreate;
}
+ /**
+ * get subtypes given the contact type
+ *
+ * @param string $contactType
+ * @return array $subTypes
+ */
+ public static function getSubtypes($contactType) {
+ $subTypes = array();
+ $types = CRM_Contact_BAO_ContactType::subTypeInfo($contactType);
+
+ if (count($types) > 0) {
+ foreach ($types as $type) {
+ $subTypes[] = $type['name'];
+ }
+ }
+ return $subTypes;
+ }
+
}
do {
$creditNoteNum++;
$creditNoteId = CRM_Utils_Array::value('credit_notes_prefix', $prefixValue) . "" . $creditNoteNum;
- $result = civicrm_api3('Contribution', 'getcount', array(
- 'sequential' => 1,
- 'creditnote_id' => $creditNoteId,
- ));
+ $params = array(1 => array($creditNoteId, 'String'));
+ $result = CRM_Core_DAO::singleValueQuery("SELECT count(id) FROM civicrm_contribution WHERE creditnote_id = %1", $params);
} while ($result > 0);
return $creditNoteId;
}
if ($this->_mid) {
- if (CRM_Member_BAO_Membership::isSubscriptionCancelled($this->_mid)) {
- CRM_Core_Error::fatal(ts('The auto renewal option for this membership looks to have been cancelled already.'));
- }
$this->_mode = 'auto_renew';
- $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_mid, 'membership', 'obj');
- $this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_mid, 'membership');
+ // CRM-18468: crid is more accurate than mid for getting
+ // subscriptionDetails, so don't get them again.
+ if (!$this->_crid) {
+ $this->_paymentProcessorObj = CRM_Financial_BAO_PaymentProcessor::getProcessorForEntity($this->_mid, 'membership', 'obj');
+ $this->_subscriptionDetails = CRM_Contribute_BAO_ContributionRecur::getSubscriptionDetails($this->_mid, 'membership');
+ }
$membershipTypes = CRM_Member_PseudoConstant::membershipType();
$membershipTypeId = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $this->_mid, 'membership_type_id');
$qf->add('text', $elementName . '_to', ts('To'), $field->attributes);
}
else {
+ if ($field->text_length) {
+ $field->attributes .= ' maxlength=' . $field->text_length;
+ if ($field->text_length < 20) {
+ $field->attributes .= ' size=' . $field->text_length;
+ }
+ }
$element = &$qf->add('text', $elementName, $label,
$field->attributes,
$useRequired && !$search
*/
public function check(&$args) {
// lets bypass a few civicrm urls from this check
- static $skip = array('civicrm/admin/setting/updateConfigBackend', 'civicrm/admin/messageTemplates');
+ $skip = array('civicrm/admin/setting/updateConfigBackend', 'civicrm/admin/messageTemplates');
+ CRM_Utils_Hook::idsException($skip);
$path = implode('/', $args);
if (in_array($path, $skip)) {
return NULL;
);
if (!$search->fetch()) {
- /* Whoops, error, don't track it. Return the base url. */
+ // Can't find either the URL or the queue. If we can find the URL then
+ // return the URL without tracking. Otherwise return the base URL.
- return CRM_Utils_System::baseURL();
+ $search->query("SELECT $turl.url as url from $turl
+ WHERE $turl.id = " . CRM_Utils_Type::escape($url_id, 'Integer')
+ );
+ if (!$search->fetch()) {
+ return CRM_Utils_System::baseURL();
+ }
+ return $search->url;
}
$open = new CRM_Mailing_Event_BAO_TrackableURLOpen();
--- /dev/null
+{* file to handle db changes in 4.6.18 during upgrade *}
+-- CRM-18516 Convert the date fields relating to group caching and acl caching timestamp
+ALTER TABLE civicrm_group CHANGE cache_date cache_date timestamp NULL DEFAULT NULL , CHANGE refresh_date refresh_date timestamp NULL DEFAULT NULL;
+ALTER TABLE civicrm_acl_cache CHANGE modified_date modified_date timestamp NULL DEFAULT NULL;
return $format;
}
- /**
- * Get the time in UTC for the current time. You can optionally send an offset from the current time if needed
- *
- * @param int $offset
- * the offset from the current time in seconds.
- *
- * @return string
- * the time in UTC
- */
- public static function getUTCTime($offset = 0) {
- $originalTimezone = date_default_timezone_get();
- date_default_timezone_set('UTC');
- $time = time() + $offset;
- $now = date('YmdHis', $time);
- date_default_timezone_set($originalTimezone);
- return $now;
- }
-
-
/**
* @param $date
* @param $dateType
);
}
+ /**
+ * This hook is called for bypass a few civicrm urls from IDS check
+ * @param array $skip list of civicrm url;
+ */
+ public static function idsException(&$skip) {
+ return self::singleton()->invoke(1, $skip, self::$_nullObject,
+ self::$_nullObject, self::$_nullObject, self::$_nullObject, self::$_nullObject,
+ 'civicrm_idsException'
+ );
+ }
+
}
--- /dev/null
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.6 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2016 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ * Just another collection of static utils functions.
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2016
+ */
+class CRM_Utils_SQL {
+
+ /**
+ * Helper function for adding the permissioned subquery from one entity onto another
+ *
+ * @param string $entity
+ * @param string $joinColumn
+ * @return array
+ */
+ public static function mergeSubquery($entity, $joinColumn = 'id') {
+ require_once 'api/v3/utils.php';
+ $baoName = _civicrm_api3_get_BAO($entity);
+ $bao = new $baoName();
+ $clauses = $subclauses = array();
+ foreach ((array) $bao->addSelectWhereClause() as $field => $vals) {
+ if ($vals && $field == $joinColumn) {
+ $clauses = array_merge($clauses, (array) $vals);
+ }
+ elseif ($vals) {
+ $subclauses[] = "$field " . implode(" AND $field ", (array) $vals);
+ }
+ }
+ if ($subclauses) {
+ $clauses[] = "IN (SELECT `$joinColumn` FROM `" . $bao->tableName() . "` WHERE " . implode(' AND ', $subclauses) . ")";
+ }
+ return $clauses;
+ }
+
+}
width: 16px;
height: 16px;
vertical-align:middle;
-}
\ No newline at end of file
+}
+
+/* No results */
+.crm-quickSearch-results.ui-menu-disabled {
+ opacity: .9;
+ background-color: #f8f8f8;
+}
+.crm-quickSearch-results.ui-menu-disabled li {
+ cursor: default;
+}
LOCK TABLES `civicrm_domain` WRITE;
/*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */;
-INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'4.6.17',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
+INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `config_backend`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,NULL,'4.6.18',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}');
/*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */;
UNLOCK TABLES;
else {
// do not set defaults to file type fields
if (cj('#' + ele).attr('type') != 'file') {
- cj('#' + ele ).val(data[ele].value).change();
+ if (ele.split("_").pop() == 'display') {
+ cj("[id^='"+ele+"']").val(data[ele].value).change();
+ }
+ else {
+ cj('#' + ele ).val(data[ele].value).change();
+ }
}
}
}
};
CRM.api3('contact', 'getquick', params).done(function(result) {
var ret = [];
- if (result.values) {
+ if (result.values.length > 0) {
+ $('#sort_name_navigation').autocomplete('widget').menu('option', 'disabled', false);
$.each(result.values, function(k, v) {
ret.push({value: v.id, label: v.data});
- })
+ });
+ } else {
+ $('#sort_name_navigation').autocomplete('widget').menu('option', 'disabled', true);
+ ret.push({value: '0', label: {/literal}'{ts escape='js'}None found.{/ts}'{literal}});
}
response(ret);
})
return false;
},
select: function (event, ui) {
- document.location = CRM.url('civicrm/contact/view', {reset: 1, cid: ui.item.value});
+ if (ui.item.value > 0) {
+ document.location = CRM.url('civicrm/contact/view', {reset: 1, cid: ui.item.value});
+ }
return false;
},
create: function() {
// Place menu in front
- $(this).autocomplete('widget').css('z-index', $('#civicrm-menu').css('z-index'));
+ $(this).autocomplete('widget')
+ .addClass('crm-quickSearch-results')
+ .css('z-index', $('#civicrm-menu').css('z-index'));
}
})
.keydown(function() {
var $menu = $('#sort_name_navigation').autocomplete('widget');
if ($('li.ui-menu-item', $menu).length === 1) {
var cid = $('li.ui-menu-item', $menu).data('ui-autocomplete-item').value;
- document.location = CRM.url('civicrm/contact/view', {reset: 1, cid: cid});
- return false;
+ if (cid > 0) {
+ document.location = CRM.url('civicrm/contact/view', {reset: 1, cid: cid});
+ return false;
+ }
}
});
// Close menu after selecting an item
EOREADME
}
+## usage: simple_replace <filename> <old-string> <new-string>
+## This is a bit like 'sed -i', but dumber and more cross-platform.
+function simple_replace() {
+ php -r 'file_put_contents($argv[1], str_replace($argv[2], $argv[3], file_get_contents($argv[1])));' "$@"
+}
+
##############################################################################
## Remove example/CLI scripts. They're not needed and increase the attack-surface.
safe_delete vendor/dompdf/dompdf/dompdf.php
safe_delete vendor/dompdf/dompdf/load_font.php
safe_delete vendor/dompdf/dompdf/www
-safe_delete vendor/dompdf/dompdf/lib/html5lib/TreeBuilder.php
safe_delete vendor/phenx/php-font-lib/www
# Remove DejaVu fonts. They add 12mb.
safe_delete vendor/dompdf/dompdf/lib/fonts/DejaVu*
make_font_cache > vendor/dompdf/dompdf/lib/fonts/dompdf_font_family_cache.dist.php
make_font_readme > vendor/dompdf/dompdf/lib/fonts/README.DejaVuFonts.txt
+
+# Remove debug_print_backtrace(), which can leak system details. Put backtrace in log.
+simple_replace vendor/dompdf/dompdf/lib/html5lib/TreeBuilder.php 'debug_print_backtrace();' 'CRM_Core_Error::backtrace("backTrace", TRUE);'
</index>
<field>
<name>modified_date</name>
- <type>date</type>
+ <title>Cache Modified Date</title>
+ <type>timestamp</type>
+ <required>false</required>
<comment>When was this cache entry last modified</comment>
<add>1.6</add>
</field>
</field>
<field>
<name>cache_date</name>
- <type>datetime</type>
+ <type>timestamp</type>
<title>Group Cache Date</title>
+ <required>false</required>
<comment>Date when we created the cache for a smart group</comment>
<add>2.1</add>
</field>
<field>
<name>refresh_date</name>
- <type>datetime</type>
+ <type>timestamp</type>
<title>Next Group Refresh Time</title>
+ <required>false</required>
<comment>Date and time when we need to refresh the cache next.</comment>
<add>4.3</add>
</field>
<?xml version="1.0" encoding="iso-8859-1" ?>
<version>
- <version_no>4.6.17</version_no>
+ <version_no>4.6.18</version_no>
</version>