First commit
This commit is contained in:
commit
c6e2478c40
13918 changed files with 2303184 additions and 0 deletions
649
sites/all/modules/civicrm/CRM/Utils/Migrate/ExportJSON.php
Normal file
649
sites/all/modules/civicrm/CRM/Utils/Migrate/ExportJSON.php
Normal file
|
@ -0,0 +1,649 @@
|
|||
<?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 |
|
||||
+--------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @package CRM
|
||||
* @copyright CiviCRM LLC (c) 2004-2017
|
||||
*/
|
||||
class CRM_Utils_Migrate_ExportJSON {
|
||||
const CHUNK_SIZE = 128;
|
||||
|
||||
protected $_contactIDs;
|
||||
|
||||
protected $_allContactIDs;
|
||||
|
||||
protected $_values;
|
||||
|
||||
protected $_discoverContacts = FALSE;
|
||||
|
||||
protected $_renameGroups = 1;
|
||||
|
||||
protected $_renameTags = 1;
|
||||
|
||||
protected $_sitePrefix = 'Site 1';
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
*/
|
||||
public function __construct(&$params) {
|
||||
foreach ($params as $name => $value) {
|
||||
$varName = '_' . $name;
|
||||
$this->$varName = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a large array of contactIDs into more manageable smaller chunks.
|
||||
*
|
||||
* @param array $contactIDs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function &splitContactIDs(&$contactIDs) {
|
||||
// contactIDs could be a real large array, so we split it up into
|
||||
// smaller chunks and then general xml for each chunk
|
||||
$chunks = array();
|
||||
$current = 0;
|
||||
$chunks[$current] = array();
|
||||
$count = 0;
|
||||
|
||||
foreach ($contactIDs as $k => $v) {
|
||||
$chunks[$current][$k] = $v;
|
||||
$count++;
|
||||
|
||||
if ($count == self::CHUNK_SIZE) {
|
||||
$current++;
|
||||
$chunks[$current] = array();
|
||||
$count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($chunks[$current])) {
|
||||
unset($chunks[$current]);
|
||||
}
|
||||
|
||||
return $chunks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a set of contact IDs get the values.
|
||||
*
|
||||
* @param array $contactIDs
|
||||
* @param array $additionalContactIDs
|
||||
*/
|
||||
public function getValues(&$contactIDs, &$additionalContactIDs) {
|
||||
|
||||
$this->contact($contactIDs);
|
||||
$this->address($contactIDs);
|
||||
$this->phone($contactIDs);
|
||||
$this->email($contactIDs);
|
||||
$this->im($contactIDs);
|
||||
$this->website($contactIDs);
|
||||
$this->note($contactIDs);
|
||||
|
||||
$this->group($contactIDs);
|
||||
$this->groupContact($contactIDs);
|
||||
$this->savedSearch($contactIDs);
|
||||
|
||||
$this->tag($contactIDs);
|
||||
$this->entityTag($contactIDs);
|
||||
|
||||
$this->relationship($contactIDs, $additionalContactIDs);
|
||||
$this->activity($contactIDs, $additionalContactIDs);
|
||||
}
|
||||
|
||||
public function metaData() {
|
||||
$optionGroupVars = array(
|
||||
'prefix_id' => 'individual_prefix',
|
||||
'suffix_id' => 'individual_suffix',
|
||||
'gender_id' => 'gender',
|
||||
'mobile_provider' => 'mobile_provider',
|
||||
'phone_type' => 'phone_type',
|
||||
'activity_type' => 'activity_type',
|
||||
'status_id' => 'activity_status_id',
|
||||
'priority_id' => 'activity_priority_id',
|
||||
'medium_id' => 'encounter_medium',
|
||||
'communication_style_id' => 'communication_style',
|
||||
'email_greeting' => 'email_greeting',
|
||||
'postal_greeting' => 'postal_greeting',
|
||||
'addressee_id' => 'addressee',
|
||||
);
|
||||
$this->optionGroup($optionGroupVars);
|
||||
|
||||
$auxilaryTables = array(
|
||||
'civicrm_location_type' => 'CRM_Core_DAO_LocationType',
|
||||
'civicrm_relationship_type' => 'CRM_Contact_DAO_RelationshipType',
|
||||
);
|
||||
$this->auxTable($auxilaryTables);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tables
|
||||
*/
|
||||
public function auxTable($tables) {
|
||||
foreach ($tables as $tableName => $daoName) {
|
||||
$fields = &$this->dbFields($daoName, TRUE);
|
||||
|
||||
$sql = "SELECT * from $tableName";
|
||||
$this->sql($sql, $tableName, $fields);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $optionGroupVars
|
||||
*/
|
||||
public function optionGroup($optionGroupVars) {
|
||||
$names = array_values($optionGroupVars);
|
||||
$str = array();
|
||||
foreach ($names as $name) {
|
||||
$str[] = "'$name'";
|
||||
}
|
||||
$nameString = implode(",", $str);
|
||||
|
||||
$sql = "
|
||||
SELECT *
|
||||
FROM civicrm_option_group
|
||||
WHERE name IN ( $nameString )
|
||||
";
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_OptionGroup', TRUE);
|
||||
$this->sql($sql, 'civicrm_option_group', $fields);
|
||||
|
||||
$sql = "
|
||||
SELECT v.*
|
||||
FROM civicrm_option_value v
|
||||
INNER JOIN civicrm_option_group g ON v.option_group_id = g.id
|
||||
WHERE g.name IN ( $nameString )
|
||||
";
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_OptionValue', TRUE);
|
||||
$this->sql($sql, 'civicrm_option_value', $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ids
|
||||
* @param string $tableName
|
||||
* @param $fields
|
||||
* @param $whereField
|
||||
* @param null $additionalWhereCond
|
||||
*/
|
||||
public function table(
|
||||
&$ids,
|
||||
$tableName,
|
||||
&$fields,
|
||||
$whereField,
|
||||
$additionalWhereCond = NULL
|
||||
) {
|
||||
if (empty($ids)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$idString = implode(',', $ids);
|
||||
|
||||
$sql = "
|
||||
SELECT *
|
||||
FROM $tableName
|
||||
WHERE $whereField IN ( $idString )
|
||||
";
|
||||
|
||||
if ($additionalWhereCond) {
|
||||
$sql .= " AND $additionalWhereCond";
|
||||
}
|
||||
|
||||
$this->sql($sql, $tableName, $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql
|
||||
* @param string $tableName
|
||||
* @param $fields
|
||||
*/
|
||||
public function sql($sql, $tableName, &$fields) {
|
||||
$dao = &CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
while ($dao->fetch()) {
|
||||
$value = array();
|
||||
foreach ($fields as $name) {
|
||||
if (empty($dao->$name)) {
|
||||
$value[$name] = NULL;
|
||||
}
|
||||
else {
|
||||
$value[$name] = $dao->$name;
|
||||
}
|
||||
}
|
||||
$this->appendValue($dao->id, $tableName, $value);
|
||||
}
|
||||
$dao->free();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function contact(&$contactIDs) {
|
||||
$fields = &$this->dbFields('CRM_Contact_DAO_Contact', TRUE);
|
||||
$this->table($contactIDs, 'civicrm_contact', $fields, 'id', NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function note(&$contactIDs) {
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_Note', TRUE);
|
||||
$this->table($contactIDs, 'civicrm_note', $fields, 'entity_id', "entity_table = 'civicrm_contact'");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function phone(&$contactIDs) {
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_Phone', TRUE);
|
||||
$this->table($contactIDs, 'civicrm_phone', $fields, 'contact_id', NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function email(&$contactIDs) {
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_Email', TRUE);
|
||||
$this->table($contactIDs, 'civicrm_email', $fields, 'contact_id', NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function im(&$contactIDs) {
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_IM', TRUE);
|
||||
$this->table($contactIDs, 'civicrm_im', $fields, 'contact_id', NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function website(&$contactIDs) {
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_Website', TRUE);
|
||||
$this->table($contactIDs, 'civicrm_website', $fields, 'contact_id', NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function address(&$contactIDs) {
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_Email', TRUE);
|
||||
$this->table($contactIDs, 'civicrm_address', $fields, 'contact_id', NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function groupContact(&$contactIDs) {
|
||||
$fields = &$this->dbFields('CRM_Contact_DAO_GroupContact', TRUE);
|
||||
$this->table($contactIDs, 'civicrm_group_contact', $fields, 'contact_id', NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo support group inheritance
|
||||
*
|
||||
* Parent child group ids are encoded in a text string
|
||||
*
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function group(&$contactIDs) {
|
||||
// handle groups only once
|
||||
static $_groupsHandled = array();
|
||||
|
||||
$ids = implode(',', $contactIDs);
|
||||
|
||||
$sql = "
|
||||
SELECT DISTINCT group_id
|
||||
FROM civicrm_group_contact
|
||||
WHERE contact_id IN ( $ids )
|
||||
";
|
||||
$dao = CRM_Core_DAO::executeQuery($sql);
|
||||
$groupIDs = array();
|
||||
while ($dao->fetch()) {
|
||||
if (!isset($_groupsHandled[$dao->group_id])) {
|
||||
$groupIDs[] = $dao->group_id;
|
||||
$_groupsHandled[$dao->group_id] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$fields = &$this->dbFields('CRM_Contact_DAO_Group', TRUE);
|
||||
$this->table($groupIDs, 'civicrm_group', $fields, 'id');
|
||||
|
||||
$this->savedSearch($groupIDs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo support search builder and custom saved searches
|
||||
* @param $groupIDs
|
||||
*/
|
||||
public function savedSearch(&$groupIDs) {
|
||||
if (empty($groupIDs)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$idString = implode(",", $groupIDs);
|
||||
$sql = "
|
||||
SELECT s.*
|
||||
FROM civicrm_saved_search s
|
||||
INNER JOIN civicrm_group g on g.saved_search_id = s.id
|
||||
WHERE g.id IN ( $idString )
|
||||
";
|
||||
|
||||
$fields = &$this->dbFields('CRM_Contact_DAO_SavedSearch', TRUE);
|
||||
$this->sql($sql, 'civicrm_saved_search', $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function entityTag(&$contactIDs) {
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_EntityTag', TRUE);
|
||||
$this->table($contactIDs, 'civicrm_entity_tag', $fields, 'entity_id', "entity_table = 'civicrm_contact'");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function tag(&$contactIDs) {
|
||||
// handle tags only once
|
||||
static $_tagsHandled = array();
|
||||
|
||||
$ids = implode(',', $contactIDs);
|
||||
|
||||
$sql = "
|
||||
SELECT DISTINCT tag_id
|
||||
FROM civicrm_entity_tag
|
||||
WHERE entity_id IN ( $ids )
|
||||
AND entity_table = 'civicrm_contact'
|
||||
";
|
||||
$dao = CRM_Core_DAO::executeQuery($sql);
|
||||
$tagIDs = array();
|
||||
while ($dao->fetch()) {
|
||||
if (!isset($_tagsHandled[$dao->tag_id])) {
|
||||
$tagIDs[] = $dao->tag_id;
|
||||
$_tagsHandled[$dao->tag_id] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$fields = &$this->dbFields('CRM_Core_DAO_Tag', TRUE);
|
||||
$this->table($tagIDs, 'civicrm_tag', $fields, 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
* @param $additionalContacts
|
||||
*/
|
||||
public function relationship(&$contactIDs, &$additionalContacts) {
|
||||
// handle relationships only once
|
||||
static $_relationshipsHandled = array();
|
||||
|
||||
$ids = implode(',', $contactIDs);
|
||||
|
||||
$sql = "(
|
||||
SELECT r.*
|
||||
FROM civicrm_relationship r
|
||||
WHERE r.contact_id_a IN ( $ids )
|
||||
) UNION (
|
||||
SELECT r.*
|
||||
FROM civicrm_relationship r
|
||||
WHERE r.contact_id_b IN ( $ids )
|
||||
)
|
||||
";
|
||||
|
||||
$fields = $this->dbFields('CRM_Contact_DAO_Relationship', TRUE);
|
||||
$dao = &CRM_Core_DAO::executeQuery($sql);
|
||||
while ($dao->fetch()) {
|
||||
if (isset($_relationshipsHandled[$dao->id])) {
|
||||
continue;
|
||||
}
|
||||
$_relationshipsHandled[$dao->id] = $dao->id;
|
||||
|
||||
$relationship = array();
|
||||
foreach ($fields as $fld) {
|
||||
if (empty($dao->$fld)) {
|
||||
$relationship[$fld] = NULL;
|
||||
}
|
||||
else {
|
||||
$relationship[$fld] = $dao->$fld;
|
||||
}
|
||||
}
|
||||
$this->appendValue($dao->id, 'civicrm_relationship', $relationship);
|
||||
|
||||
$this->addAdditionalContacts(array(
|
||||
$dao->contact_id_a,
|
||||
$dao->contact_id_b,
|
||||
),
|
||||
$additionalContacts
|
||||
);
|
||||
}
|
||||
$dao->free();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
* @param $additionalContacts
|
||||
*/
|
||||
public function activity(&$contactIDs, &$additionalContacts) {
|
||||
static $_activitiesHandled = array();
|
||||
$activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate');
|
||||
$assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
|
||||
$targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts);
|
||||
$ids = implode(',', $contactIDs);
|
||||
|
||||
// query framing returning all contacts in valid activity
|
||||
$sql = "
|
||||
SELECT a.*, ac.id as acID, ac.activity_id, ac.contact_id, ac.record_type_id
|
||||
FROM civicrm_activity a
|
||||
INNER JOIN civicrm_activity_contact ac ON ac.activity_id = a.id
|
||||
WHERE ac.contact_id IN ( $ids )
|
||||
AND (a.activity_type_id != 3 AND a.activity_type_id != 20)
|
||||
";
|
||||
|
||||
$fields = &$this->dbFields('CRM_Activity_DAO_Activity', TRUE);
|
||||
|
||||
$dao = &CRM_Core_DAO::executeQuery($sql);
|
||||
while ($dao->fetch()) {
|
||||
// adding source, target and assignee contacts in additional contacts array
|
||||
$this->addAdditionalContacts(array($dao->contact_id),
|
||||
$additionalContacts
|
||||
);
|
||||
|
||||
// append values of activity contacts
|
||||
$activityContacts = array(
|
||||
'id' => $dao->acID,
|
||||
'contact_id' => $dao->contact_id,
|
||||
'activity_id' => $dao->activity_id,
|
||||
'record_type_id' => $dao->record_type_id,
|
||||
);
|
||||
$this->appendValue($dao->acID, 'civicrm_activity_contact', $activityContacts);
|
||||
|
||||
if (isset($_activitiesHandled[$dao->id])) {
|
||||
continue;
|
||||
}
|
||||
$_activitiesHandled[$dao->id] = $dao->id;
|
||||
|
||||
$activity = array();
|
||||
foreach ($fields as $fld) {
|
||||
if (empty($dao->$fld)) {
|
||||
$activity[$fld] = NULL;
|
||||
}
|
||||
else {
|
||||
$activity[$fld] = $dao->$fld;
|
||||
}
|
||||
}
|
||||
|
||||
// append activity value
|
||||
$this->appendValue($dao->id, 'civicrm_activity', $activity);
|
||||
}
|
||||
$dao->free();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $name
|
||||
* @param $value
|
||||
*/
|
||||
public function appendValue($id, $name, $value) {
|
||||
if (empty($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($this->_values[$name])) {
|
||||
$this->_values[$name] = array();
|
||||
$this->_values[$name][] = array_keys($value);
|
||||
}
|
||||
$this->_values[$name][] = array_values($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $daoName
|
||||
* @param bool $onlyKeys
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dbFields($daoName, $onlyKeys = FALSE) {
|
||||
static $_fieldsRetrieved = array();
|
||||
|
||||
if (!isset($_fieldsRetrieved[$daoName])) {
|
||||
$_fieldsRetrieved[$daoName] = array();
|
||||
$daoFile = str_replace('_',
|
||||
DIRECTORY_SEPARATOR,
|
||||
$daoName
|
||||
) . '.php';
|
||||
include_once $daoFile;
|
||||
|
||||
$daoFields = &$daoName::fields();
|
||||
|
||||
foreach ($daoFields as $key => & $value) {
|
||||
$_fieldsRetrieved[$daoName][$value['name']] = array(
|
||||
'uniqueName' => $key,
|
||||
'type' => $value['type'],
|
||||
'title' => CRM_Utils_Array::value('title', $value, NULL),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($onlyKeys) {
|
||||
return array_keys($_fieldsRetrieved[$daoName]);
|
||||
}
|
||||
else {
|
||||
return $_fieldsRetrieved[$daoName];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
* @param $additionalContacts
|
||||
*/
|
||||
public function addAdditionalContacts($contactIDs, &$additionalContacts) {
|
||||
if (!$this->_discoverContacts) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($contactIDs as $cid) {
|
||||
if ($cid &&
|
||||
!isset($this->_allContactIDs[$cid]) &&
|
||||
!isset($additionalContacts[$cid])
|
||||
) {
|
||||
$additionalContacts[$cid] = $cid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $contactIDs
|
||||
*/
|
||||
public function export(&$contactIDs) {
|
||||
$chunks = &$this->splitContactIDs($contactIDs);
|
||||
|
||||
$additionalContactIDs = array();
|
||||
|
||||
foreach ($chunks as $chunk) {
|
||||
$this->getValues($chunk, $additionalContactIDs);
|
||||
}
|
||||
|
||||
if (!empty($additionalContactIDs)) {
|
||||
$this->_allContactIDs = $this->_allContactIDs + $additionalContactIDs;
|
||||
$this->export($additionalContactIDs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileName
|
||||
* @param null $lastExportTime
|
||||
* @param bool $discoverContacts
|
||||
*/
|
||||
public function run(
|
||||
$fileName,
|
||||
$lastExportTime = NULL,
|
||||
$discoverContacts = FALSE
|
||||
) {
|
||||
$this->_discoverContacts = $discoverContacts;
|
||||
|
||||
if (!$lastExportTime) {
|
||||
$sql = "
|
||||
SELECT id
|
||||
FROM civicrm_contact
|
||||
";
|
||||
}
|
||||
else {
|
||||
$sql = "(
|
||||
SELECT DISTINCT entity_id
|
||||
FROM civicrm_log
|
||||
WHERE entity_table = 'civicrm_contact'
|
||||
AND modified_date >= $lastExportTime
|
||||
) UNION (
|
||||
SELECT DISTINCT contact_id
|
||||
FROM civicrm_subscription_history
|
||||
WHERE date >= $lastExportTime
|
||||
)
|
||||
";
|
||||
}
|
||||
|
||||
$dao = &CRM_Core_DAO::executeQuery($sql);
|
||||
|
||||
$contactIDs = array();
|
||||
while ($dao->fetch()) {
|
||||
$contactIDs[$dao->id] = $dao->id;
|
||||
}
|
||||
|
||||
$this->_allContactIDs = $contactIDs;
|
||||
$this->_values = array();
|
||||
|
||||
$this->metaData();
|
||||
|
||||
$this->export($contactIDs);
|
||||
|
||||
$json = json_encode($this->_values, JSON_NUMERIC_CHECK);
|
||||
file_put_contents($fileName,
|
||||
$json
|
||||
);
|
||||
|
||||
// print_r( json_decode( $json ) );
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue