Skip to content

Commit e595392

Browse files
committed
PersistableEnum trait
1 parent 4ced542 commit e595392

File tree

9 files changed

+256
-1
lines changed

9 files changed

+256
-1
lines changed

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ if test "$PHP_MONGODB" != "no"; then
125125
src/BSON/ObjectId.c \
126126
src/BSON/ObjectIdInterface.c \
127127
src/BSON/Persistable.c \
128+
src/BSON/PersistableEnum.c \
128129
src/BSON/Regex.c \
129130
src/BSON/RegexInterface.c \
130131
src/BSON/Serializable.c \

config.w32

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ if (PHP_MONGODB != "no") {
121121

122122
EXTENSION("mongodb", "php_phongo.c", null, PHP_MONGODB_CFLAGS);
123123
MONGODB_ADD_SOURCES("/src", "phongo_apm.c phongo_bson.c phongo_bson_encode.c phongo_client.c phongo_compat.c phongo_error.c phongo_execute.c phongo_ini.c phongo_util.c");
124-
MONGODB_ADD_SOURCES("/src/BSON", "Binary.c BinaryInterface.c DBPointer.c Decimal128.c Decimal128Interface.c Int64.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c Persistable.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c");
124+
MONGODB_ADD_SOURCES("/src/BSON", "Binary.c BinaryInterface.c DBPointer.c Decimal128.c Decimal128Interface.c Int64.c Javascript.c JavascriptInterface.c MaxKey.c MaxKeyInterface.c MinKey.c MinKeyInterface.c ObjectId.c ObjectIdInterface.c Persistable.c PersistableEnum.c Regex.c RegexInterface.c Serializable.c Symbol.c Timestamp.c TimestampInterface.c Type.c Undefined.c Unserializable.c UTCDateTime.c UTCDateTimeInterface.c functions.c");
125125
MONGODB_ADD_SOURCES("/src/MongoDB", "BulkWrite.c ClientEncryption.c Command.c Cursor.c CursorId.c CursorInterface.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c ServerApi.c ServerDescription.c Session.c TopologyDescription.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c");
126126
MONGODB_ADD_SOURCES("/src/MongoDB/Exception", "AuthenticationException.c BulkWriteException.c CommandException.c ConnectionException.c ConnectionTimeoutException.c EncryptionException.c Exception.c ExecutionTimeoutException.c InvalidArgumentException.c LogicException.c RuntimeException.c ServerException.c SSLConnectionException.c UnexpectedValueException.c WriteException.c");
127127
MONGODB_ADD_SOURCES("/src/MongoDB/Monitoring", "CommandFailedEvent.c CommandStartedEvent.c CommandSubscriber.c CommandSucceededEvent.c SDAMSubscriber.c Subscriber.c ServerChangedEvent.c ServerClosedEvent.c ServerHeartbeatFailedEvent.c ServerHeartbeatStartedEvent.c ServerHeartbeatSucceededEvent.c ServerOpeningEvent.c TopologyChangedEvent.c TopologyClosedEvent.c TopologyOpeningEvent.c functions.c");

php_phongo.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ PHP_MINIT_FUNCTION(mongodb) /* {{{ */
217217
php_phongo_minkey_init_ce(INIT_FUNC_ARGS_PASSTHRU);
218218
php_phongo_objectid_init_ce(INIT_FUNC_ARGS_PASSTHRU);
219219
php_phongo_persistable_init_ce(INIT_FUNC_ARGS_PASSTHRU);
220+
php_phongo_persistableenum_init_ce(INIT_FUNC_ARGS_PASSTHRU);
220221
php_phongo_regex_init_ce(INIT_FUNC_ARGS_PASSTHRU);
221222
php_phongo_symbol_init_ce(INIT_FUNC_ARGS_PASSTHRU);
222223
php_phongo_timestamp_init_ce(INIT_FUNC_ARGS_PASSTHRU);

src/BSON/PersistableEnum.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2014-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <php.h>
18+
19+
#include "php_phongo.h"
20+
#include "phongo_error.h"
21+
#include "PersistableEnum_arginfo.h"
22+
23+
zend_class_entry* php_phongo_persistableenum_ce;
24+
25+
PHP_METHOD(MongoDB_BSON_PersistableEnum, bsonSerialize)
26+
{
27+
PHONGO_PARSE_PARAMETERS_NONE();
28+
29+
RETVAL_ZVAL(getThis(), 1, 0);
30+
convert_to_array(return_value);
31+
32+
return;
33+
}
34+
35+
PHP_METHOD(MongoDB_BSON_PersistableEnum, bsonUnserialize)
36+
{
37+
zval* data;
38+
39+
PHONGO_PARSE_PARAMETERS_START(1, 1)
40+
Z_PARAM_ARRAY(data)
41+
PHONGO_PARSE_PARAMETERS_END();
42+
43+
return;
44+
} /* }}} */
45+
46+
void php_phongo_persistableenum_init_ce(INIT_FUNC_ARGS) /* {{{ */
47+
{
48+
php_phongo_persistableenum_ce = register_class_MongoDB_BSON_PersistableEnum();
49+
} /* }}} */

src/BSON/PersistableEnum.stub.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
/**
4+
* @generate-class-entries static
5+
* @generate-function-entries
6+
*/
7+
8+
namespace MongoDB\BSON;
9+
10+
trait PersistableEnum
11+
{
12+
public final function bsonSerialize(): array {}
13+
14+
public final function bsonUnserialize(array $data): void {}
15+
}

src/BSON/PersistableEnum_arginfo.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* This is a generated file, edit the .stub.php file instead.
2+
* Stub hash: db87873800da8dfaf4b3235eed97254593c9b83d */
3+
4+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_MongoDB_BSON_PersistableEnum_bsonSerialize, 0, 0, IS_ARRAY, 0)
5+
ZEND_END_ARG_INFO()
6+
7+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_MongoDB_BSON_PersistableEnum_bsonUnserialize, 0, 1, IS_VOID, 0)
8+
ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0)
9+
ZEND_END_ARG_INFO()
10+
11+
12+
ZEND_METHOD(MongoDB_BSON_PersistableEnum, bsonSerialize);
13+
ZEND_METHOD(MongoDB_BSON_PersistableEnum, bsonUnserialize);
14+
15+
16+
static const zend_function_entry class_MongoDB_BSON_PersistableEnum_methods[] = {
17+
ZEND_ME(MongoDB_BSON_PersistableEnum, bsonSerialize, arginfo_class_MongoDB_BSON_PersistableEnum_bsonSerialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
18+
ZEND_ME(MongoDB_BSON_PersistableEnum, bsonUnserialize, arginfo_class_MongoDB_BSON_PersistableEnum_bsonUnserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
19+
ZEND_FE_END
20+
};
21+
22+
static zend_class_entry *register_class_MongoDB_BSON_PersistableEnum(void)
23+
{
24+
zend_class_entry ce, *class_entry;
25+
26+
INIT_NS_CLASS_ENTRY(ce, "MongoDB\\BSON", "PersistableEnum", class_MongoDB_BSON_PersistableEnum_methods);
27+
class_entry = zend_register_internal_class_ex(&ce, NULL);
28+
class_entry->ce_flags |= ZEND_ACC_TRAIT;
29+
30+
return class_entry;
31+
}

src/phongo_classes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ extern zend_class_entry* php_phongo_bulkwriteexception_ce;
322322

323323
extern zend_class_entry* php_phongo_type_ce;
324324
extern zend_class_entry* php_phongo_persistable_ce;
325+
extern zend_class_entry* php_phongo_persistableenum_ce;
325326
extern zend_class_entry* php_phongo_unserializable_ce;
326327
extern zend_class_entry* php_phongo_serializable_ce;
327328
extern zend_class_entry* php_phongo_binary_ce;
@@ -373,6 +374,7 @@ extern void php_phongo_maxkey_init_ce(INIT_FUNC_ARGS);
373374
extern void php_phongo_minkey_init_ce(INIT_FUNC_ARGS);
374375
extern void php_phongo_objectid_init_ce(INIT_FUNC_ARGS);
375376
extern void php_phongo_persistable_init_ce(INIT_FUNC_ARGS);
377+
extern void php_phongo_persistableenum_init_ce(INIT_FUNC_ARGS);
376378
extern void php_phongo_regex_init_ce(INIT_FUNC_ARGS);
377379
extern void php_phongo_serializable_init_ce(INIT_FUNC_ARGS);
378380
extern void php_phongo_symbol_init_ce(INIT_FUNC_ARGS);

tests/bson/bson-enum-004.phpt

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
--TEST--
2+
Enums implementing Persistable using PersistableEnum trait
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php skip_if_php_version('<', '8.1.0'); ?>
6+
--FILE--
7+
<?php
8+
9+
require_once __DIR__ . '/../utils/basic.inc';
10+
11+
enum MyEnum implements MongoDB\BSON\Persistable
12+
{
13+
use MongoDB\BSON\PersistableEnum;
14+
15+
case foo;
16+
}
17+
18+
enum MyBackedEnum: string implements MongoDB\BSON\Persistable
19+
{
20+
use MongoDB\BSON\PersistableEnum;
21+
22+
case foo = 'bar';
23+
}
24+
25+
$tests = [
26+
/* There is no practical reason to use an enum as a root document, since it
27+
* cannot have an "_id" field, but we'll test this anyway since we're only
28+
* using BSON functions and not round-tripping data through the server. */
29+
MyEnum::foo,
30+
MyBackedEnum::foo,
31+
['myEnum' => MyEnum::foo],
32+
['myBackedEnum' => MyBackedEnum::foo],
33+
];
34+
35+
foreach ($tests as $document) {
36+
$bson = fromPHP($document);
37+
echo "Test ", toJSON($bson), "\n";
38+
hex_dump($bson);
39+
var_dump(toPHP($bson));
40+
echo "\n";
41+
}
42+
43+
?>
44+
===DONE===
45+
<?php exit(0); ?>
46+
--EXPECTF--
47+
Test { "__pclass" : { "$binary" : "TXlFbnVt", "$type" : "80" }, "name" : "foo" }
48+
0 : 28 00 00 00 05 5f 5f 70 63 6c 61 73 73 00 06 00 [(....__pclass...]
49+
10 : 00 00 80 4d 79 45 6e 75 6d 02 6e 61 6d 65 00 04 [...MyEnum.name..]
50+
20 : 00 00 00 66 6f 6f 00 00 [...foo..]
51+
enum(MyEnum::foo)
52+
53+
Test { "__pclass" : { "$binary" : "TXlCYWNrZWRFbnVt", "$type" : "80" }, "name" : "foo", "value" : "bar" }
54+
0 : 3d 00 00 00 05 5f 5f 70 63 6c 61 73 73 00 0c 00 [=....__pclass...]
55+
10 : 00 00 80 4d 79 42 61 63 6b 65 64 45 6e 75 6d 02 [...MyBackedEnum.]
56+
20 : 6e 61 6d 65 00 04 00 00 00 66 6f 6f 00 02 76 61 [name.....foo..va]
57+
30 : 6c 75 65 00 04 00 00 00 62 61 72 00 00 [lue.....bar..]
58+
enum(MyBackedEnum::foo)
59+
60+
Test { "myEnum" : { "__pclass" : { "$binary" : "TXlFbnVt", "$type" : "80" }, "name" : "foo" } }
61+
0 : 35 00 00 00 03 6d 79 45 6e 75 6d 00 28 00 00 00 [5....myEnum.(...]
62+
10 : 05 5f 5f 70 63 6c 61 73 73 00 06 00 00 00 80 4d [.__pclass......M]
63+
20 : 79 45 6e 75 6d 02 6e 61 6d 65 00 04 00 00 00 66 [yEnum.name.....f]
64+
30 : 6f 6f 00 00 00 [oo...]
65+
object(stdClass)#%d (%d) {
66+
["myEnum"]=>
67+
enum(MyEnum::foo)
68+
}
69+
70+
Test { "myBackedEnum" : { "__pclass" : { "$binary" : "TXlCYWNrZWRFbnVt", "$type" : "80" }, "name" : "foo", "value" : "bar" } }
71+
0 : 50 00 00 00 03 6d 79 42 61 63 6b 65 64 45 6e 75 [P....myBackedEnu]
72+
10 : 6d 00 3d 00 00 00 05 5f 5f 70 63 6c 61 73 73 00 [m.=....__pclass.]
73+
20 : 0c 00 00 00 80 4d 79 42 61 63 6b 65 64 45 6e 75 [.....MyBackedEnu]
74+
30 : 6d 02 6e 61 6d 65 00 04 00 00 00 66 6f 6f 00 02 [m.name.....foo..]
75+
40 : 76 61 6c 75 65 00 04 00 00 00 62 61 72 00 00 00 [value.....bar...]
76+
object(stdClass)#%d (%d) {
77+
["myBackedEnum"]=>
78+
enum(MyBackedEnum::foo)
79+
}
80+
81+
===DONE===

tests/bson/bson-enum_error-003.phpt

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
--TEST--
2+
Typemap specifies enum that does not implement Unserializable
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"; ?>
5+
<?php skip_if_php_version('<', '8.1.0'); ?>
6+
--FILE--
7+
<?php
8+
9+
require_once __DIR__ . '/../utils/basic.inc';
10+
11+
enum MyEnum
12+
{
13+
const NOT_A_CASE = 1;
14+
case foo;
15+
}
16+
17+
echo throws(function() {
18+
toPHP(
19+
fromJSON('{}'),
20+
['root' => MyEnum::class]
21+
);
22+
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
23+
24+
echo throws(function() {
25+
toPHP(
26+
fromJSON('{"name": "NOT_A_CONSTANT"}'),
27+
['root' => MyEnum::class]
28+
);
29+
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
30+
31+
echo throws(function() {
32+
toPHP(
33+
fromJSON('{"name": "NOT_A_CASE"}'),
34+
['root' => MyEnum::class]
35+
);
36+
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
37+
38+
echo throws(function() {
39+
toPHP(
40+
fromJSON('{"myEnum": {}}'),
41+
['fieldPaths' => ['myEnum' => MyEnum::class]]
42+
);
43+
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
44+
45+
echo throws(function() {
46+
toPHP(
47+
fromJSON('{"myEnum": {"name": "NOT_A_CONSTANT"}}'),
48+
['fieldPaths' => ['myEnum' => MyEnum::class]]
49+
);
50+
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
51+
52+
echo throws(function() {
53+
toPHP(
54+
fromJSON('{"myEnum": {"name": "NOT_A_CASE"}}'),
55+
['fieldPaths' => ['myEnum' => MyEnum::class]]
56+
);
57+
}, MongoDB\Driver\Exception\InvalidArgumentException::class), "\n";
58+
59+
?>
60+
===DONE===
61+
<?php exit(0); ?>
62+
--EXPECT--
63+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
64+
Class MyEnum does not implement MongoDB\BSON\Unserializable
65+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
66+
Class MyEnum does not implement MongoDB\BSON\Unserializable
67+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
68+
Class MyEnum does not implement MongoDB\BSON\Unserializable
69+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
70+
Class MyEnum does not implement MongoDB\BSON\Unserializable
71+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
72+
Class MyEnum does not implement MongoDB\BSON\Unserializable
73+
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
74+
Class MyEnum does not implement MongoDB\BSON\Unserializable
75+
===DONE===

0 commit comments

Comments
 (0)