MDL-64140 core_message: add get_unread_conversation_counts() web service

This commit is contained in:
Jake Dallimore 2018-11-26 10:54:18 +08:00
parent 7f6f45c460
commit b402a163e3
4 changed files with 291 additions and 42 deletions

View File

@ -1143,6 +1143,15 @@ $functions = array(
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
'ajax' => true,
),
'core_message_get_unread_conversation_counts' => array(
'classname' => 'core_message_external',
'methodname' => 'get_unread_conversation_counts',
'classpath' => 'message/externallib.php',
'description' => 'Retrieve a list of unread conversation counts, indexed by type.',
'type' => 'read',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
'ajax' => true,
),
'core_message_get_conversation_members' => array(
'classname' => 'core_message_external',
'methodname' => 'get_conversation_members',

View File

@ -4480,4 +4480,79 @@ class core_message_external extends external_api {
]
);
}
/**
* Returns description of method parameters for get_unread_conversation_counts() method.
*
* @return external_function_parameters
*/
public static function get_unread_conversation_counts_parameters() {
return new external_function_parameters(
[
'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0)
]
);
}
/**
* Returns an array of unread conversation counts for the various types of conversations, including favourites.
*
* Return format:
* [
* 'favourites' => 0,
* 'types' => [
* \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
* \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
* ]
* ]
*
* @param int $userid the id of the user whose counts we are fetching.
* @return array the array of unread conversation counts, indexed by type.
* @throws moodle_exception if the current user cannot perform this action.
*/
public static function get_unread_conversation_counts(int $userid) {
global $CFG, $USER;
// All the business logic checks that really shouldn't be in here.
if (empty($CFG->messaging)) {
throw new moodle_exception('disabled', 'message');
}
if (empty($userid)) {
$userid = $USER->id;
}
$params = ['userid' => $userid];
$params = self::validate_parameters(self::get_unread_conversation_counts_parameters(), $params);
$systemcontext = context_system::instance();
self::validate_context($systemcontext);
if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
throw new moodle_exception('You do not have permission to perform this action.');
}
return \core_message\api::get_unread_conversation_counts($params['userid']);
}
/**
* Get unread conversation counts return description.
*
* @return external_description
*/
public static function get_unread_conversation_counts_returns() {
return new external_single_structure(
[
'favourites' => new external_value(PARAM_INT, 'Total number of unread favourite conversations'),
'types' => new external_single_structure(
[
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => new external_value(PARAM_INT,
'Total number of unread individual conversations'),
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => new external_value(PARAM_INT,
'Total number of unread group conversations'),
]
),
]
);
}
}

View File

@ -6143,14 +6143,14 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
[
'type' => $typeindividual,
'users' => [$user1, $user2],
'messages' => [$user1, $user2],
'messages' => [$user1, $user2, $user2],
'favourites' => [$user1],
'enabled' => null // Individual conversations cannot be disabled.
],
[
'type' => $typeindividual,
'users' => [$user1, $user3],
'messages' => [$user1, $user1],
'messages' => [$user1, $user3, $user1],
'favourites' => [],
'enabled' => null // Individual conversations cannot be disabled.
],
@ -6161,10 +6161,17 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'favourites' => [],
'enabled' => true
],
[
'type' => $typegroup,
'users' => [$user2, $user3, $user4],
'messages' => [$user2, $user3, $user4],
'favourites' => [],
'enabled' => true
],
[
'type' => $typegroup,
'users' => [$user6, $user7],
'messages' => [$user6, $user7],
'messages' => [$user6, $user7, $user7],
'favourites' => [$user6],
'enabled' => false
],
@ -6183,20 +6190,28 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user5],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
]],
'deletedusers' => []
],
'No individual conversations, 1 group conversation' => [
'No individual conversations, 2 group conversations' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user4],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'deletedusers' => []
],
@ -6205,31 +6220,43 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user1],
'expected' => ['favourites' => 1, 'types' => [
'expectedcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'expectedunreadcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'deletedusers' => []
],
'1 individual conversation, 1 group conversation' => [
'1 individual conversation, 2 group conversations' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user2],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'deletedusers' => []
],
'1 group conversation only' => [
'2 group conversations only' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user4],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'deletedusers' => []
],
@ -6238,7 +6265,11 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'deletemessagesuser' => $user1,
'deletemessages' => [0],
'arguments' => [$user1],
'expected' => ['favourites' => 1, 'types' => [
'expectedcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'expectedunreadcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
@ -6247,9 +6278,13 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'All conversation types, delete a message from individual non-favourited, messages remaining' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => $user1,
'deletemessages' => [2],
'deletemessages' => [3],
'arguments' => [$user1],
'expected' => ['favourites' => 1, 'types' => [
'expectedcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'expectedunreadcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
@ -6258,9 +6293,13 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'All conversation types, delete all messages from individual favourited, no messages remaining' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => $user1,
'deletemessages' => [0, 1],
'deletemessages' => [0, 1, 2],
'arguments' => [$user1],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
@ -6269,9 +6308,13 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'All conversation types, delete all messages from individual non-favourited, no messages remaining' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => $user1,
'deletemessages' => [2, 3],
'deletemessages' => [3, 4, 5],
'arguments' => [$user1],
'expected' => ['favourites' => 1, 'types' => [
'expectedcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'expectedunreadcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
@ -6280,31 +6323,43 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'All conversation types, delete all messages from individual favourited, no messages remaining, different user' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => $user1,
'deletemessages' => [0, 1],
'deletemessages' => [0, 1, 2],
'arguments' => [$user2],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'deletedusers' => []
],
'All conversation types, delete all messages from individual non-favourited, no messages remaining, different user' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => $user1,
'deletemessages' => [2, 3],
'deletemessages' => [3, 4, 5],
'arguments' => [$user3],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 2
]],
'deletedusers' => []
],
'All conversation types, delete some messages from group non-favourited, messages remaining,' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => $user1,
'deletemessages' => [4, 5],
'deletemessages' => [6, 7],
'arguments' => [$user1],
'expected' => ['favourites' => 1, 'types' => [
'expectedcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'expectedunreadcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
@ -6313,12 +6368,16 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'All conversation types, delete all messages from group non-favourited, no messages remaining,' => [
'conversationConfigs' => $conversations,
'deletemessagesuser' => $user1,
'deletemessages' => [4, 5, 6, 7],
'deletemessages' => [6, 7, 8, 9],
'arguments' => [$user1],
'expected' => ['favourites' => 1, 'types' => [
'expectedcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'expectedunreadcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
]],
'deletedusers' => []
],
'All conversation types, another user soft deleted' => [
@ -6326,7 +6385,11 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user1],
'expected' => ['favourites' => 1, 'types' => [
'expectedcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'expectedunreadcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
@ -6337,7 +6400,11 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user1],
'expected' => ['favourites' => 1, 'types' => [
'expectedcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
'expectedunreadcounts' => ['favourites' => 1, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 1
]],
@ -6348,7 +6415,11 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user6],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
]],
@ -6359,7 +6430,11 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user7],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
]],
@ -6370,7 +6445,11 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
'deletemessagesuser' => null,
'deletemessages' => [],
'arguments' => [$user8],
'expected' => ['favourites' => 0, 'types' => [
'expectedcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
]],
'expectedunreadcounts' => ['favourites' => 0, 'types' => [
\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0
]],
@ -6387,7 +6466,8 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
* @param int $deletemessagesuser The user who is deleting the messages
* @param array $deletemessages The list of messages to delete (by index)
* @param array $arguments Arguments for the count conversations function
* @param array $expected The expected result
* @param array $expectedcounts the expected conversation counts
* @param array $expectedunreadcounts the expected unread conversation counts
* @param array $deletedusers the array of users to soft delete.
*/
public function test_get_conversation_counts(
@ -6395,7 +6475,8 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
$deletemessagesuser,
$deletemessages,
$arguments,
$expected,
$expectedcounts,
$expectedunreadcounts,
$deletedusers
) {
$this->resetAfterTest();
@ -6454,10 +6535,94 @@ class core_message_externallib_testcase extends externallib_advanced_testcase {
$counts = core_message_external::get_conversation_counts(...$arguments);
$counts = external_api::clean_returnvalue(core_message_external::get_conversation_counts_returns(), $counts);
$this->assertEquals($expected['favourites'], $counts['favourites']);
$this->assertEquals($expected['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL],
$this->assertEquals($expectedcounts['favourites'], $counts['favourites']);
$this->assertEquals($expectedcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL],
$counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]);
$this->assertEquals($expected['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP],
$this->assertEquals($expectedcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP],
$counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP]);
}
/**
* Test the get_unread_conversation_counts() function.
*
* @dataProvider test_get_conversation_counts_test_cases()
* @param array $conversationconfigs Conversations to create
* @param int $deletemessagesuser The user who is deleting the messages
* @param array $deletemessages The list of messages to delete (by index)
* @param array $arguments Arguments for the count conversations function
* @param array $expectedcounts the expected conversation counts
* @param array $expectedunreadcounts the expected unread conversation counts
* @param array $deletedusers the list of users to soft-delete.
*/
public function test_get_unread_conversation_counts(
$conversationconfigs,
$deletemessagesuser,
$deletemessages,
$arguments,
$expectedcounts,
$expectedunreadcounts,
$deletedusers
) {
$this->resetAfterTest();
$generator = $this->getDataGenerator();
$users = [
$generator->create_user(),
$generator->create_user(),
$generator->create_user(),
$generator->create_user(),
$generator->create_user(),
$generator->create_user(),
$generator->create_user(),
$generator->create_user()
];
$deleteuser = !is_null($deletemessagesuser) ? $users[$deletemessagesuser] : null;
$this->setUser($users[$arguments[0]]);
$arguments[0] = $users[$arguments[0]]->id;
$systemcontext = \context_system::instance();
$conversations = [];
$messageids = [];
foreach ($conversationconfigs as $config) {
$conversation = \core_message\api::create_conversation(
$config['type'],
array_map(function($userindex) use ($users) {
return $users[$userindex]->id;
}, $config['users']),
null,
($config['enabled'] ?? true)
);
foreach ($config['messages'] as $userfromindex) {
$userfrom = $users[$userfromindex];
$messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id);
}
foreach ($config['favourites'] as $userfromindex) {
$userfrom = $users[$userfromindex];
$usercontext = \context_user::instance($userfrom->id);
$ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
$ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext);
}
$conversations[] = $conversation;
}
foreach ($deletemessages as $messageindex) {
\core_message\api::delete_message($deleteuser->id, $messageids[$messageindex]);
}
foreach ($deletedusers as $deleteduser) {
delete_user($users[$deleteduser]);
}
$counts = core_message_external::get_unread_conversation_counts(...$arguments);
$counts = external_api::clean_returnvalue(core_message_external::get_unread_conversation_counts_returns(), $counts);
$this->assertEquals($expectedunreadcounts['favourites'], $counts['favourites']);
$this->assertEquals($expectedunreadcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL],
$counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]);
$this->assertEquals($expectedunreadcounts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP],
$counts['types'][\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP]);
}
}

View File

@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2018112500.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2018112500.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.