1 /**
2  *     Copyright 2018 Couchbase, 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 /**
18  * Sort by the hit score.
19  */
20 #include "couchbase.h"
21 
22 typedef struct {
23     PCBC_ZEND_OBJECT_PRE
24     zend_bool descending;
25     PCBC_ZEND_OBJECT_POST
26 } pcbc_search_sort_score_t;
27 
28 #if PHP_VERSION_ID >= 70000
pcbc_search_sort_score_fetch_object(zend_object * obj)29 static inline pcbc_search_sort_score_t *pcbc_search_sort_score_fetch_object(zend_object *obj)
30 {
31     return (pcbc_search_sort_score_t *)((char *)obj - XtOffsetOf(pcbc_search_sort_score_t, std));
32 }
33 #define Z_SEARCH_SORT_SCORE_OBJ(zo) (pcbc_search_sort_score_fetch_object(zo))
34 #define Z_SEARCH_SORT_SCORE_OBJ_P(zv) (pcbc_search_sort_score_fetch_object(Z_OBJ_P(zv)))
35 #else
36 #define Z_SEARCH_SORT_SCORE_OBJ(zo) ((pcbc_search_sort_score_t *)zo)
37 #define Z_SEARCH_SORT_SCORE_OBJ_P(zv) ((pcbc_search_sort_score_t *)zend_object_store_get_object(zv TSRMLS_CC))
38 #endif
39 
40 #define LOGARGS(lvl) LCB_LOG_##lvl, NULL, "pcbc/search_sort_score", __FILE__, __LINE__
41 
42 zend_class_entry *pcbc_search_sort_score_ce;
43 
44 /* {{{ proto void SearchSortScore::__construct() */
PHP_METHOD(SearchSortScore,__construct)45 PHP_METHOD(SearchSortScore, __construct)
46 {
47     throw_pcbc_exception("Accessing private constructor.", LCB_EINVAL);
48 }
49 /* }}} */
50 
51 /* {{{ proto \Couchbase\SearchSortScore SearchSortScore::descending(boolean $val)
52  */
PHP_METHOD(SearchSortScore,descending)53 PHP_METHOD(SearchSortScore, descending)
54 {
55     pcbc_search_sort_score_t *obj;
56     zend_bool descending = 0;
57     int rv;
58 
59     rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &descending);
60     if (rv == FAILURE) {
61         RETURN_NULL();
62     }
63 
64     obj = Z_SEARCH_SORT_SCORE_OBJ_P(getThis());
65     obj->descending = descending;
66 
67     RETURN_ZVAL(getThis(), 1, 0);
68 } /* }}} */
69 
70 /* {{{ proto array SearchSortScore::jsonSerialize()
71  */
PHP_METHOD(SearchSortScore,jsonSerialize)72 PHP_METHOD(SearchSortScore, jsonSerialize)
73 {
74     pcbc_search_sort_score_t *obj;
75     int rv;
76 
77     rv = zend_parse_parameters_none();
78     if (rv == FAILURE) {
79         RETURN_NULL();
80     }
81 
82     obj = Z_SEARCH_SORT_SCORE_OBJ_P(getThis());
83     array_init(return_value);
84     ADD_ASSOC_STRING(return_value, "by", "score");
85     ADD_ASSOC_BOOL_EX(return_value, "desc", obj->descending);
86 } /* }}} */
87 
88 ZEND_BEGIN_ARG_INFO_EX(ai_SearchSortScore_none, 0, 0, 0)
89 ZEND_END_ARG_INFO()
90 
91 ZEND_BEGIN_ARG_INFO_EX(ai_SearchSortScore_descending, 0, 0, 1)
92 ZEND_ARG_INFO(0, descending)
93 ZEND_END_ARG_INFO()
94 
95 // clang-format off
96 zend_function_entry search_sort_score_methods[] = {
97     PHP_ME(SearchSortScore, __construct, ai_SearchSortScore_none, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL | ZEND_ACC_CTOR)
98     PHP_ME(SearchSortScore, jsonSerialize, ai_SearchSortScore_none, ZEND_ACC_PUBLIC)
99     PHP_ME(SearchSortScore, descending, ai_SearchSortScore_descending, ZEND_ACC_PUBLIC)
100     PHP_FE_END
101 };
102 // clang-format on
103 
pcbc_search_sort_score_init(zval * return_value TSRMLS_DC)104 void pcbc_search_sort_score_init(zval *return_value TSRMLS_DC)
105 {
106     pcbc_search_sort_score_t *obj;
107 
108     object_init_ex(return_value, pcbc_search_sort_score_ce);
109     obj = Z_SEARCH_SORT_SCORE_OBJ_P(return_value);
110     obj->descending = 0;
111 }
112 
113 zend_object_handlers search_sort_score_handlers;
114 
search_sort_score_free_object(pcbc_free_object_arg * object TSRMLS_DC)115 static void search_sort_score_free_object(pcbc_free_object_arg *object TSRMLS_DC) /* {{{ */
116 {
117     pcbc_search_sort_score_t *obj = Z_SEARCH_SORT_SCORE_OBJ(object);
118 
119     zend_object_std_dtor(&obj->std TSRMLS_CC);
120 #if PHP_VERSION_ID < 70000
121     efree(obj);
122 #endif
123 } /* }}} */
124 
search_sort_score_create_object(zend_class_entry * class_type TSRMLS_DC)125 static pcbc_create_object_retval search_sort_score_create_object(zend_class_entry *class_type TSRMLS_DC)
126 {
127     pcbc_search_sort_score_t *obj = NULL;
128 
129     obj = PCBC_ALLOC_OBJECT_T(pcbc_search_sort_score_t, class_type);
130 
131     zend_object_std_init(&obj->std, class_type TSRMLS_CC);
132     object_properties_init(&obj->std, class_type);
133 
134 #if PHP_VERSION_ID >= 70000
135     obj->std.handlers = &search_sort_score_handlers;
136     return &obj->std;
137 #else
138     {
139         zend_object_value ret;
140         ret.handle = zend_objects_store_put(obj, (zend_objects_store_dtor_t)zend_objects_destroy_object,
141                                             search_sort_score_free_object, NULL TSRMLS_CC);
142         ret.handlers = &search_sort_score_handlers;
143         return ret;
144     }
145 #endif
146 }
147 
pcbc_search_sort_score_get_debug_info(zval * object,int * is_temp TSRMLS_DC)148 static HashTable *pcbc_search_sort_score_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
149 {
150     pcbc_search_sort_score_t *obj = NULL;
151 #if PHP_VERSION_ID >= 70000
152     zval retval;
153 #else
154     zval retval = zval_used_for_init;
155 #endif
156 
157     *is_temp = 1;
158     obj = Z_SEARCH_SORT_SCORE_OBJ_P(object);
159 
160     array_init(&retval);
161     ADD_ASSOC_STRING(&retval, "by", "score");
162     ADD_ASSOC_BOOL_EX(&retval, "desc", obj->descending);
163     return Z_ARRVAL(retval);
164 } /* }}} */
165 
PHP_MINIT_FUNCTION(SearchSortScore)166 PHP_MINIT_FUNCTION(SearchSortScore)
167 {
168     zend_class_entry ce;
169 
170     INIT_NS_CLASS_ENTRY(ce, "Couchbase", "SearchSortScore", search_sort_score_methods);
171     pcbc_search_sort_score_ce = zend_register_internal_class_ex(&ce, pcbc_search_sort_ce
172 #if PHP_VERSION_ID < 70000
173                                                                 ,
174                                                                 NULL
175 #endif
176                                                                     TSRMLS_CC);
177     pcbc_search_sort_score_ce->create_object = search_sort_score_create_object;
178     PCBC_CE_DISABLE_SERIALIZATION(pcbc_search_sort_score_ce);
179 
180     zend_class_implements(pcbc_search_sort_score_ce TSRMLS_CC, 1, pcbc_json_serializable_ce);
181 
182     memcpy(&search_sort_score_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
183     search_sort_score_handlers.get_debug_info = pcbc_search_sort_score_get_debug_info;
184 #if PHP_VERSION_ID >= 70000
185     search_sort_score_handlers.free_obj = search_sort_score_free_object;
186     search_sort_score_handlers.offset = XtOffsetOf(pcbc_search_sort_score_t, std);
187 #endif
188     return SUCCESS;
189 }
190