430 lines
14 KiB
PHP
430 lines
14 KiB
PHP
<?php
|
|
/*
|
|
+--------------------------------------------------------------------+
|
|
| CiviCRM version 4.7 |
|
|
+--------------------------------------------------------------------+
|
|
| Copyright CiviCRM LLC (c) 2004-2017 |
|
|
+--------------------------------------------------------------------+
|
|
| 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 |
|
|
+--------------------------------------------------------------------+
|
|
*/
|
|
|
|
/**
|
|
* This api exposes CiviCRM system functionality.
|
|
*
|
|
* Includes caching, logging, and checking system functionality.
|
|
*
|
|
* @package CiviCRM_APIv3
|
|
*/
|
|
|
|
/**
|
|
* Flush all system caches.
|
|
*
|
|
* @param array $params
|
|
* Input parameters.
|
|
* - triggers: bool, whether to drop/create SQL triggers; default: FALSE
|
|
* - session: bool, whether to reset the CiviCRM session data; default: FALSE
|
|
*
|
|
* @return array
|
|
*/
|
|
function civicrm_api3_system_flush($params) {
|
|
CRM_Core_Invoke::rebuildMenuAndCaches(
|
|
CRM_Utils_Array::value('triggers', $params, FALSE),
|
|
CRM_Utils_Array::value('session', $params, FALSE)
|
|
);
|
|
return civicrm_api3_create_success();
|
|
}
|
|
|
|
/**
|
|
* Adjust Metadata for Flush action.
|
|
*
|
|
* The metadata is used for setting defaults, documentation & validation.
|
|
*
|
|
* @param array $params
|
|
* Array of parameters determined by getfields.
|
|
*/
|
|
function _civicrm_api3_system_flush_spec(&$params) {
|
|
$params['triggers'] = array(
|
|
'title' => 'Triggers',
|
|
'description' => 'rebuild triggers (boolean)',
|
|
'type' => CRM_Utils_Type::T_BOOLEAN,
|
|
);
|
|
$params['session'] = array(
|
|
'title' => 'Sessions',
|
|
'description' => 'refresh sessions (boolean)',
|
|
'type' => CRM_Utils_Type::T_BOOLEAN,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* System.Check API specification (optional).
|
|
*
|
|
* This is used for documentation and validation.
|
|
*
|
|
* @param array $spec
|
|
* Description of fields supported by this API call.
|
|
*
|
|
* @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
|
|
*/
|
|
function _civicrm_api3_system_check_spec(&$spec) {
|
|
$spec['id'] = array(
|
|
'title' => 'ID',
|
|
'description' => 'Not a real identifier - do not use',
|
|
'type' => CRM_Utils_Type::T_INT,
|
|
);
|
|
$spec['name'] = array(
|
|
'title' => 'Name',
|
|
'description' => 'Unique identifier',
|
|
'type' => CRM_Utils_Type::T_STRING,
|
|
);
|
|
$spec['title'] = array(
|
|
'title' => 'Title',
|
|
'description' => 'Short title text',
|
|
'type' => CRM_Utils_Type::T_STRING,
|
|
);
|
|
$spec['message'] = array(
|
|
'title' => 'Message',
|
|
'description' => 'Long description html',
|
|
'type' => CRM_Utils_Type::T_STRING,
|
|
);
|
|
$spec['help'] = array(
|
|
'title' => 'Help',
|
|
'description' => 'Optional extra help (html string)',
|
|
'type' => CRM_Utils_Type::T_STRING,
|
|
);
|
|
$spec['severity'] = array(
|
|
'title' => 'Severity',
|
|
'description' => 'Psr\Log\LogLevel string',
|
|
'type' => CRM_Utils_Type::T_STRING,
|
|
'options' => array_combine(CRM_Utils_Check::getSeverityList(), CRM_Utils_Check::getSeverityList()),
|
|
);
|
|
$spec['severity_id'] = array(
|
|
'title' => 'Severity ID',
|
|
'description' => 'Integer representation of Psr\Log\LogLevel',
|
|
'type' => CRM_Utils_Type::T_INT,
|
|
'options' => CRM_Utils_Check::getSeverityList(),
|
|
);
|
|
$spec['is_visible'] = array(
|
|
'title' => 'is visible',
|
|
'description' => '0 if message has been hidden by the user',
|
|
'type' => CRM_Utils_Type::T_BOOLEAN,
|
|
);
|
|
$spec['hidden_until'] = array(
|
|
'title' => 'Hidden_until',
|
|
'description' => 'When will hidden message be visible again?',
|
|
'type' => CRM_Utils_Type::T_DATE,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* System Check API.
|
|
*
|
|
* @param array $params
|
|
*
|
|
* @return array
|
|
* API result descriptor; return items are alert codes/messages
|
|
* @see civicrm_api3_create_success
|
|
* @see civicrm_api3_create_error
|
|
* @throws API_Exception
|
|
*/
|
|
function civicrm_api3_system_check($params) {
|
|
// array(array('name'=> $, 'severity'=>$, ...))
|
|
$id = 1;
|
|
$returnValues = $fields = array();
|
|
_civicrm_api3_system_check_spec($fields);
|
|
|
|
// array(CRM_Utils_Check_Message)
|
|
$messages = CRM_Utils_Check::checkAll();
|
|
|
|
foreach ($messages as $msg) {
|
|
$returnValues[] = $msg->toArray() + array('id' => $id++);
|
|
}
|
|
|
|
return _civicrm_api3_basic_array_get('systemCheck', $params, $returnValues, "id", array_keys($fields));
|
|
}
|
|
|
|
/**
|
|
* Log entry to system log table.
|
|
*
|
|
* @param array $params
|
|
*
|
|
* @return array
|
|
*/
|
|
function civicrm_api3_system_log($params) {
|
|
$log = new CRM_Utils_SystemLogger();
|
|
// This part means fields with separate db storage are accepted as params which kind of seems more intuitive to me
|
|
// because I felt like not doing this required a bunch of explanation in the spec function - but perhaps other won't see it as helpful?
|
|
if (!isset($params['context'])) {
|
|
$params['context'] = array();
|
|
}
|
|
$specialFields = array('contact_id', 'hostname');
|
|
foreach ($specialFields as $specialField) {
|
|
if (isset($params[$specialField]) && !isset($params['context'])) {
|
|
$params['context'][$specialField] = $params[$specialField];
|
|
}
|
|
}
|
|
$returnValues = $log->log($params['level'], $params['message'], $params['context']);
|
|
return civicrm_api3_create_success($returnValues, $params, 'System', 'Log');
|
|
}
|
|
|
|
/**
|
|
* Metadata for log function.
|
|
*
|
|
* @param array $params
|
|
*/
|
|
function _civicrm_api3_system_log_spec(&$params) {
|
|
$params['level'] = array(
|
|
'title' => 'Log Level',
|
|
'description' => 'Log level as described in PSR3 (info, debug, warning etc)',
|
|
'type' => CRM_Utils_Type::T_STRING,
|
|
'api.required' => TRUE,
|
|
);
|
|
$params['message'] = array(
|
|
'title' => 'Log Message',
|
|
'description' => 'Standardised message string, you can also ',
|
|
'type' => CRM_Utils_Type::T_STRING,
|
|
'api.required' => TRUE,
|
|
);
|
|
$params['context'] = array(
|
|
'title' => 'Log Context',
|
|
'description' => 'An array of additional data to store.',
|
|
'type' => CRM_Utils_Type::T_LONGTEXT,
|
|
'api.default' => array(),
|
|
);
|
|
$params['contact_id'] = array(
|
|
'title' => 'Log Contact ID',
|
|
'description' => 'Optional ID of relevant contact',
|
|
'type' => CRM_Utils_Type::T_INT,
|
|
);
|
|
$params['hostname'] = array(
|
|
'title' => 'Log Hostname',
|
|
'description' => 'Optional name of host',
|
|
'type' => CRM_Utils_Type::T_STRING,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* System.Get API.
|
|
*
|
|
* @param array $params
|
|
*
|
|
* @return array
|
|
*/
|
|
function civicrm_api3_system_get($params) {
|
|
$config = CRM_Core_Config::singleton();
|
|
$returnValues = array(
|
|
array(
|
|
'version' => CRM_Utils_System::version(), // deprecated in favor of civi.version
|
|
'uf' => CIVICRM_UF, // deprecated in favor of cms.type
|
|
'php' => array(
|
|
'version' => phpversion(),
|
|
'time' => time(),
|
|
'tz' => date_default_timezone_get(),
|
|
'sapi' => php_sapi_name(),
|
|
'extensions' => get_loaded_extensions(),
|
|
'ini' => _civicrm_api3_system_get_redacted_ini(),
|
|
),
|
|
'mysql' => array(
|
|
'version' => CRM_Core_DAO::singleValueQuery('SELECT @@version'),
|
|
'time' => CRM_Core_DAO::singleValueQuery('SELECT unix_timestamp()'),
|
|
'vars' => _civicrm_api3_system_get_redacted_mysql(),
|
|
),
|
|
'cms' => array(
|
|
'version' => $config->userSystem->getVersion(),
|
|
'type' => CIVICRM_UF,
|
|
'modules' => CRM_Core_Module::collectStatuses($config->userSystem->getModules()),
|
|
),
|
|
'civi' => array(
|
|
'version' => CRM_Utils_System::version(),
|
|
'dev' => (bool) CRM_Utils_System::isDevelopment(),
|
|
'components' => array_keys(CRM_Core_Component::getEnabledComponents()),
|
|
'extensions' => preg_grep(
|
|
'/^uninstalled$/',
|
|
CRM_Extension_System::singleton()->getManager()->getStatuses(),
|
|
PREG_GREP_INVERT
|
|
),
|
|
'multidomain' => CRM_Core_DAO::singleValueQuery('SELECT count(*) FROM civicrm_domain') > 1,
|
|
'settings' => _civicrm_api3_system_get_redacted_settings(),
|
|
'exampleUrl' => CRM_Utils_System::url('civicrm/example', NULL, TRUE, NULL, FALSE),
|
|
),
|
|
'http' => array(
|
|
'software' => CRM_Utils_Array::value('SERVER_SOFTWARE', $_SERVER),
|
|
'forwarded' => !empty($_SERVER['HTTP_X_FORWARDED_FOR']) || !empty($_SERVER['X_FORWARDED_PROTO']),
|
|
'port' => (empty($_SERVER['SERVER_PORT']) || $_SERVER['SERVER_PORT'] == 80 || $_SERVER['SERVER_PORT'] == 443) ? 'Standard' : 'Nonstandard',
|
|
),
|
|
'os' => array(
|
|
'type' => php_uname('s'),
|
|
'release' => php_uname('r'),
|
|
'version' => php_uname('v'),
|
|
'machine' => php_uname('m'),
|
|
),
|
|
),
|
|
);
|
|
|
|
return civicrm_api3_create_success($returnValues, $params, 'System', 'get');
|
|
}
|
|
|
|
/**
|
|
* Generate a sanitized/anonymized/redacted dump of the PHP configuration.
|
|
*
|
|
* Some INI fields contain site-identifying information (SII) -- e.g. URLs,
|
|
* hostnames, file paths, IP addresses, passwords, or free-form comments
|
|
* could be used to identify a site or gain access to its resources.
|
|
*
|
|
* A number of INI fields have been examined to determine whether they
|
|
* contain SII. Approved fields are put in a whitelist; all other fields
|
|
* are redacted.
|
|
*
|
|
* Redaction hides the substance of a field but does not completely omit
|
|
* all information. Consider the field 'mail.log' - setting this field
|
|
* has a functional effect (it enables or disables the logging behavior)
|
|
* and also points to particular file. Empty values (FALSE/NULL/0/"")
|
|
* will pass through redaction, but all other values will be replaced
|
|
* by a string (eg "REDACTED"). This roughly indicates whether the
|
|
* option is enabled/disabled without giving away its content.
|
|
*
|
|
* @return array
|
|
*/
|
|
function _civicrm_api3_system_get_redacted_ini() {
|
|
static $whitelist = NULL;
|
|
if ($whitelist === NULL) {
|
|
$whitelist = _civicrm_api3_system_get_whitelist(__DIR__ . '/System/ini-whitelist.txt');
|
|
}
|
|
|
|
$inis = ini_get_all(NULL, FALSE);
|
|
$result = array();
|
|
foreach ($inis as $k => $v) {
|
|
if (empty($v) || in_array($k, $whitelist)) {
|
|
$result[$k] = $v;
|
|
}
|
|
else {
|
|
$result[$k] = 'REDACTED';
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Generate ae sanitized/anonymized/redacted dump of MySQL configuration.
|
|
*
|
|
* @return array
|
|
* @see _civicrm_api3_system_get_redacted_ini
|
|
*/
|
|
function _civicrm_api3_system_get_redacted_mysql() {
|
|
static $whitelist = NULL;
|
|
if ($whitelist === NULL) {
|
|
$whitelist = _civicrm_api3_system_get_whitelist(__DIR__ . '/System/mysql-whitelist.txt');
|
|
}
|
|
|
|
$inis = ini_get_all(NULL, FALSE);
|
|
$result = array();
|
|
$dao = CRM_Core_DAO::executeQuery('SHOW VARIABLES');
|
|
while ($dao->fetch()) {
|
|
if (empty($dao->Variable_name) || in_array($dao->Variable_name, $whitelist)) {
|
|
$result[$dao->Variable_name] = $dao->Value;
|
|
}
|
|
else {
|
|
$result[$dao->Variable_name] = 'REDACTED';
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Get redacted settings.
|
|
*
|
|
* @return array
|
|
* @throws CiviCRM_API3_Exception
|
|
*/
|
|
function _civicrm_api3_system_get_redacted_settings() {
|
|
static $whitelist = NULL;
|
|
if ($whitelist === NULL) {
|
|
$whitelist = _civicrm_api3_system_get_whitelist(__DIR__ . '/System/setting-whitelist.txt');
|
|
}
|
|
|
|
$apiResult = civicrm_api3('Setting', 'get', array());
|
|
$result = array();
|
|
foreach ($apiResult['values'] as $settings) {
|
|
foreach ($settings as $key => $value) {
|
|
if (in_array($key, $whitelist)) {
|
|
$result[$key] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Read a whitelist.
|
|
*
|
|
* @param string $whitelistFile
|
|
* Name of a file. Each line is a field name. Comments begin with "#".
|
|
* @return array
|
|
*/
|
|
function _civicrm_api3_system_get_whitelist($whitelistFile) {
|
|
$whitelist = array_filter(
|
|
explode("\n", file_get_contents($whitelistFile)),
|
|
function ($k) {
|
|
return !empty($k) && !preg_match('/^\s*#/', $k);
|
|
}
|
|
);
|
|
return $whitelist;
|
|
}
|
|
|
|
/**
|
|
* Update log table structures.
|
|
*
|
|
* This updates the engine type if defined in the hook and changes the field type
|
|
* for log_conn_id to reflect CRM-18193.
|
|
*/
|
|
function civicrm_api3_system_updatelogtables() {
|
|
$schema = new CRM_Logging_Schema();
|
|
$schema->updateLogTableSchema();
|
|
return civicrm_api3_create_success(1);
|
|
}
|
|
|
|
/**
|
|
* Update indexes.
|
|
*
|
|
* This adds any indexes that exist in the schema but not the database.
|
|
*/
|
|
function civicrm_api3_system_updateindexes() {
|
|
CRM_Core_BAO_SchemaHandler::createMissingIndices(CRM_Core_BAO_SchemaHandler::getMissingIndices(TRUE));
|
|
return civicrm_api3_create_success(1);
|
|
}
|
|
|
|
/**
|
|
* Creates missing log tables.
|
|
*
|
|
* CRM-20838 - This adds any missing log tables into the database.
|
|
*/
|
|
function civicrm_api3_system_createmissinglogtables() {
|
|
$schema = new CRM_Logging_Schema();
|
|
$missingLogTables = $schema->getMissingLogTables();
|
|
if (!empty($missingLogTables)) {
|
|
foreach ($missingLogTables as $tableName) {
|
|
$schema->fixSchemaDifferencesFor($tableName, NULL, FALSE);
|
|
}
|
|
}
|
|
return civicrm_api3_create_success(1);
|
|
}
|