Develop and Download Open Source Software

Browse CVS Repository

Contents of /xoonips/AL/xnpal.cc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.9 - (show annotations) (download) (as text)
Wed Dec 1 01:54:32 2004 UTC (19 years, 4 months ago) by aga
Branch: MAIN
Changes since 1.8: +17 -0 lines
File MIME type: text/x-c++src
・getLastErrorString()を作成.

1 /*
2 VPAL: Visiome Platform Abstract Layer
3
4 zend_parse_parameters??hp4.1.0??綽?荀?
5 .so???<?ゃ?????????荀????????贋????舟??鴻????
6 C++?с????extern "C"{}, BEGIN/END_EXTERN_C()??綽?荀???
7 */
8
9
10 #include <stdio.h>
11 #include "criteria.h"
12 #include "common.h"
13 #include "commonal.h"
14 #include "session.h"
15 #include "group.h"
16 #include "account.h"
17 #include "vpal.h"
18
19 // for inet_aton
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23
24 // global variables
25 MYSQL *mysql = NULL;
26
27
28 /* declaration of functions to be exported */
29 extern "C" {
30 ZEND_FUNCTION(first_module );
31 ZEND_FUNCTION(vp_initialize_db );
32 ZEND_FUNCTION(vp_login_user );
33 ZEND_FUNCTION(vp_logout_user );
34 ZEND_FUNCTION(vp_create_session );
35 ZEND_FUNCTION(vp_get_session );
36 ZEND_FUNCTION(vp_is_activated );
37 ZEND_FUNCTION(vp_activate );
38 ZEND_FUNCTION(vp_get_account_count );
39 ZEND_FUNCTION(vp_delete_account );
40 ZEND_FUNCTION(vp_get_account );
41 ZEND_FUNCTION(vp_get_accounts );
42 ZEND_FUNCTION(vp_insert_account );
43 ZEND_FUNCTION(vp_update_account );
44 ZEND_FUNCTION(vp_dump_uids );
45 ZEND_FUNCTION(vp_get_group_count );
46 ZEND_FUNCTION(vp_get_groups_by_uid );
47 ZEND_FUNCTION(vp_is_group_admin );
48 ZEND_FUNCTION(vp_dump_gids );
49 ZEND_FUNCTION(vp_dump_group_admins );
50 /*
51 ZEND_FUNCTION(vp_delete_member );
52 ZEND_FUNCTION(vp_insert_member );
53 ZEND_FUNCTION(vp_get_members );
54 ZEND_FUNCTION(vp_delete_group );
55 ZEND_FUNCTION(vp_insert_group );
56 */
57 ZEND_FUNCTION(vp_update_group );
58 ZEND_FUNCTION(vp_get_group );
59 ZEND_FUNCTION(vp_get_groups );
60 ZEND_FUNCTION(vp_is_moderator );
61 ZEND_FUNCTION(vp_get_uid );
62
63 ZEND_FUNCTION(vp_get_last_error_string );
64
65 ZEND_FUNCTION(vp_test_criteria );
66 ZEND_FUNCTION(vp_test_uids );
67 };
68 /* compiled function list so Zend knows what's in this module */
69 zend_function_entry vpalmod_functions[] =
70 {
71 ZEND_FE(first_module ,NULL)
72 ZEND_FE(vp_initialize_db ,NULL)
73 ZEND_FE(vp_login_user ,NULL)
74 ZEND_FE(vp_logout_user ,NULL)
75 ZEND_FE(vp_create_session ,NULL)
76 ZEND_FE(vp_get_session ,NULL)
77 ZEND_FE(vp_is_activated ,NULL)
78 ZEND_FE(vp_activate ,NULL)
79 ZEND_FE(vp_get_account_count ,NULL)
80 ZEND_FE(vp_delete_account ,NULL)
81 ZEND_FE(vp_get_account ,NULL)
82 ZEND_FE(vp_get_accounts ,NULL)
83 ZEND_FE(vp_insert_account ,NULL)
84 ZEND_FE(vp_update_account ,NULL)
85 ZEND_FE(vp_dump_uids ,NULL)
86 ZEND_FE(vp_get_group_count ,NULL)
87 ZEND_FE(vp_get_groups_by_uid ,NULL)
88 ZEND_FE(vp_is_group_admin ,NULL)
89 ZEND_FE(vp_dump_gids ,NULL)
90 ZEND_FE(vp_dump_group_admins ,NULL)
91 /*
92 ZEND_FE(vp_delete_member ,NULL)
93 ZEND_FE(vp_insert_member ,NULL)
94 ZEND_FE(vp_get_members ,NULL)
95 ZEND_FE(vp_delete_group ,NULL)
96 ZEND_FE(vp_insert_group ,NULL)
97 */
98 ZEND_FE(vp_update_group ,NULL)
99 ZEND_FE(vp_get_group ,NULL)
100 ZEND_FE(vp_get_groups ,NULL)
101 ZEND_FE(vp_is_moderator ,NULL)
102 ZEND_FE(vp_get_uid ,NULL)
103 ZEND_FE(vp_get_last_error_string ,NULL)
104 ZEND_FE(vp_test_criteria ,NULL)
105 ZEND_FE(vp_test_uids ,NULL)
106 {NULL, NULL, NULL}
107 };
108
109 /* compiled module information */
110 zend_module_entry vpalmod_module_entry =
111 {
112 STANDARD_MODULE_HEADER,
113 "Visiome Platform Abstract Layer",
114 vpalmod_functions,
115 NULL,
116 NULL,
117 NULL,
118 NULL,
119 NULL,
120 NO_VERSION_YET,
121 STANDARD_MODULE_PROPERTIES
122 };
123
124 /* implement standard "stub" routine to introduce ourselves to Zend */
125 #if COMPILE_DL_FIRST_MODULE
126 BEGIN_EXTERN_C()
127 ZEND_GET_MODULE(vpalmod)
128 END_EXTERN_C()
129 #endif
130
131 /* implement function that is meant to be made available to PHP */
132 ZEND_FUNCTION(first_module)
133 {
134 long parameter;
135 // if(ZEND_NUM_ARGS() != 2) WRONG_PARAM_COUNT;
136 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &parameter) == FAILURE) {
137 return;
138 }
139 parameter++;
140 RETURN_LONG(parameter);
141 }
142 /** zval????C????絖?????緇?????
143 */
144 char *getZvalString( zval **p ){
145 convert_to_string_ex(p);
146 return Z_STRVAL_PP(p); //(**p).value.str.val;
147 }
148
149 /** zval????int??緇?????
150 */
151 int getZvalInt( zval **p ){
152 convert_to_long_ex(p);
153 return Z_LVAL_PP(p); // (int)(**p).value.lval;
154 }
155
156 // keylen????鮎??0????????
157 static void print_hash_key( int res, const char *key, uint keyLen, ulong index ){
158 zend_printf( "print_hash_key : key=0x%08x keylen=%08d index=%08d<br> ", key, keyLen, index );
159 if ( res == HASH_KEY_IS_STRING ){
160 char *p = new char[keyLen+1];
161 memcpy( p, key, keyLen );
162 p[keyLen] = 0;
163 zend_printf( " key is string[%s]<br>\n", p );
164 }
165 else {
166 zend_printf( " key is integer[%d]<br>\n", index );
167 }
168 }
169
170
171 /** zval**????criteria_t?????????????????????鴻??????紊掩??????getResult()!=RES_OK
172 * criteria :
173 array( 'start'=>0, 'rows'=>10,
174 'orders'=>array(
175 array('name'=>'id','order'=>'0'),
176 array('name'=>'timestamp','name'=>'1'), ...)
177 ); ??????就???f?渇????
178 */
179 class zCriteria_t : public criteria {
180 private:
181 result_t result;
182 public:
183 // pz: array('name'=>'timestamp','name'=>'1')
184 // ????????orderby??篏???????申????
185 void setOrder( zval *pz ){
186 char *column = 0;
187 order_t order = (order_t)0;
188
189 HashPosition pos;
190 zval **ppzTmp = 0;
191 int res2;
192 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(pz), &pos);
193 while ( (res2=zend_hash_get_current_data_ex(Z_ARRVAL_P(pz), (void **)&ppzTmp, &pos)) == SUCCESS ) {
194 char *key = 0;
195 uint keyLen = 0;
196 ulong index = 0;
197 int keyType = zend_hash_get_current_key_ex(Z_ARRVAL_P(pz), &key, &keyLen, &index, false/*duplicate flag*/, &pos );
198 if ( keyType == HASH_KEY_IS_STRING/*1*/ || keyType == HASH_KEY_IS_LONG/*2*/ ){
199 print_hash_key( keyType, key, keyLen, index );
200 if ( strncasecmp( key, "column", keyLen ) == 0 && keyLen == 7 ){
201 SEPARATE_ZVAL(ppzTmp);
202 column = getZvalString(ppzTmp);
203 // zend_printf( "column=%s<br>\n", column );
204 }
205 else if ( strncasecmp( key, "order", keyLen ) == 0 && keyLen == 6 ){
206 SEPARATE_ZVAL(ppzTmp);
207 order = (order_t)getZvalInt(ppzTmp);
208 // zend_printf( "order=%d<br>\n", order );
209 }
210 }
211
212 zend_hash_move_forward_ex(Z_ARRVAL_P(pz), &pos);
213 }
214 if ( column ){
215 orderby *o = new orderby( column, order );
216 addOrderBy( o );
217 }
218
219 result = RES_OK;
220 }
221
222 // pz: array( array('column'=>'hoge','order'=>'1'), array('column'=>'huga','order'=>'2'), ...)
223 void setOrders( zval *pz ){
224 HashPosition pos;
225
226 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(pz), &pos);
227
228 zval **ppzTmp = 0;
229 int res2;
230 while ( (res2=zend_hash_get_current_data_ex(Z_ARRVAL_P(pz), (void **)&ppzTmp, &pos)) == SUCCESS ) {
231 char *key = 0;
232 uint keyLen = 0;
233 ulong index = 0;
234 int keyType = zend_hash_get_current_key_ex(Z_ARRVAL_P(pz), &key, &keyLen, &index, false/*duplicate flag*/, &pos );
235 if ( keyType == HASH_KEY_IS_STRING/*1*/ || keyType == HASH_KEY_IS_LONG/*2*/ ){
236 print_hash_key( keyType, key, keyLen, index );
237 setOrder( *ppzTmp );
238 }
239 zend_hash_move_forward_ex(Z_ARRVAL_P(pz), &pos);
240 }
241 result = RES_OK;
242 }
243
244 void initialize( zval *pz ){
245 HashPosition pos;
246 zval **ppzTmp = 0;
247 int res2;
248 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(pz), &pos);
249 while ( (res2=zend_hash_get_current_data_ex(Z_ARRVAL_P(pz), (void **)&ppzTmp, &pos)) == SUCCESS ) {
250 char *key = 0;
251 uint keyLen = 0;
252 ulong index = 0;
253 int keyType = zend_hash_get_current_key_ex(Z_ARRVAL_P(pz), &key, &keyLen, &index, false/*duplicate flag*/, &pos );
254 if ( keyType == HASH_KEY_IS_STRING/*1*/ || keyType == HASH_KEY_IS_LONG/*2*/ ){
255 print_hash_key( keyType, key, keyLen, index );
256 if ( strncasecmp( key, "start", keyLen ) == 0 && keyLen == 6 ){
257 SEPARATE_ZVAL(ppzTmp);
258 int tmp = getZvalInt(ppzTmp);
259 // zend_printf( "start=%d<br>\n", tmp );
260 setLimit( tmp, getLimitRows() );
261 }
262 else if ( strncasecmp( key, "rows", keyLen ) == 0 && keyLen == 5 ){
263 SEPARATE_ZVAL(ppzTmp);
264 int tmp = getZvalInt(ppzTmp);
265 // zend_printf( "rows=%d<br>\n", tmp );
266 setLimit( getLimitStart(), tmp );
267 }
268 else if ( strncasecmp( key, "orders", keyLen ) == 0 && keyLen == 7 ){
269 setOrders( *ppzTmp );
270 }
271 else
272 ; // ignore unknown key
273 }
274 else
275 ; // ignore bad key
276 zend_hash_move_forward_ex(Z_ARRVAL_P(pz), &pos);
277 }
278 result = RES_OK;
279 }
280 zCriteria_t() : criteria(){ result = RES_ERROR; }
281 zCriteria_t( zval *pz ) : criteria(){ initialize(pz); }
282 zCriteria_t( zval **ppz ) : criteria() { initialize(*ppz); }
283 result_t getResult(){ return result; };
284
285 void dump(){
286 zend_printf( "dumping zCriteria...<br>\n" );
287 zend_printf( "result=%d<br>\n", (int)result );
288 zend_printf( "start=%d, rows=%d<br>\n", getLimitStart(), getLimitRows() );
289 const orderby *p = headOrderBy();
290 while ( p ){
291 zend_printf( "column=%s, order=%d<br>\n", p->getColumn(), p->getOrder() );
292 p = nextOrderBy();
293 }
294 }
295 };
296
297
298 class zAccount_t : public account {
299 private:
300 result_t result;
301 public:
302 void initialize(zval *pz){
303 ; // todo
304 }
305 zAccount_t() : account(){ result = RES_ERROR; }
306 zAccount_t( zval *pz ) : account(){ initialize(pz); }
307 zAccount_t( zval **ppz ) : account() { initialize(*ppz); }
308 result_t getResult(){ return result; };
309 };
310
311 /** zval**????(userid_t *puid,int uidLen)?????????????????????鴻??????紊掩??????getResult()!=RES_OK
312 uids : array( '1', '3', '4', '6', ... ); ??????就??????
313 */
314 class zUIDs_t {
315 private:
316 result_t result;
317 userid_t *pUID;
318 int len;
319 public:
320 zUIDs_t(){
321 pUID = 0;
322 len = 0;
323 result = RES_ERROR;
324 }
325
326 zUIDs_t( zval *pza ){
327 pUID = 0;
328 len = 0;
329 result = RES_ERROR;
330
331 if ( Z_TYPE_P(pza) != IS_ARRAY ){
332 result = RES_ERROR;
333 }
334 else {
335 len = zend_hash_num_elements(Z_ARRVAL_P(pza));
336 if(len == 0) {
337 pUID = new userid_t[1];
338 result = RES_OK;
339 }
340 else {
341 /* php/ext/standard/string.c ? implode??????????????????
342 zend_hash_*???????ャ?<?潟???c????????????????鐚?
343 */
344 zval **tmp;
345 HashPosition pos;
346 int i = 0;
347 pUID = new userid_t[len];
348
349 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(pza), &pos);
350 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(pza), (void **) &tmp, &pos) == SUCCESS ) {
351 SEPARATE_ZVAL(tmp); // zend.arguments.write-safety.html ????/span>
352 convert_to_long_ex(tmp);
353 if ( i < len )
354 pUID[i++] = Z_LVAL_PP(tmp);
355 zend_hash_move_forward_ex(Z_ARRVAL_P(pza), &pos);
356 }
357 len = i;
358 result = RES_OK;
359 }
360 }
361 }
362
363 ~zUIDs_t(){
364 if ( pUID ) delete[] pUID;
365 }
366 result_t getResult(){ return result; }
367 userid_t *getPUID(){ return pUID; }
368 int getLen(){ return len; }
369 void dump(){
370 zend_printf( "dumping zUIDs...<br>\n" );
371 zend_printf( "result=%d<br>\n", (int)result );
372 zend_printf( "len=%d<br>\n", len );
373 for ( int i = 0; i < len; i++ ){
374 zend_printf( "pUID[%d] = %d<br>\n", i, pUID[i] );
375 }
376 }
377 };
378
379 /**
380 *
381 * uids_t????????PHP???????????????
382 *
383 * @param pUID 紊?????????serid_t??????
384 * @param len pUID?????????激??
385 * @param pz 紊???腟??????吾??莨若??????(??????羝??帥?с????????
386 * @return RES_OK
387 *
388 */
389 result_t uidsToZval( userid_t *pUID, int len, zval **ppz )
390 {
391 zend_hash_clean( Z_ARRVAL_PP(ppz) );
392
393 // add UIDs
394 for ( int i = 0; i < len; i++ ){
395 add_next_index_long(*ppz, (long)(pUID[i]) );
396 }
397
398 return RES_OK;
399 }
400 /** groupid_t ?? zval
401 */
402 result_t gidsToZval( groupid_t *pGID, int len, zval **ppz )
403 {
404 zend_hash_clean( Z_ARRVAL_PP(ppz) );
405
406 // add GIDs
407 for ( int i = 0; i < len; i++ ){
408 add_next_index_long(*ppz, (long)(pGID[i]) );
409 }
410
411 return RES_OK;
412 }
413
414 result_t accountToZval( const account_t *pAccount, zval *z )
415 {
416 zend_hash_clean( z -> value.ht );
417
418 add_assoc_long( z, "uid", pAccount -> getUID( ) );
419 add_assoc_string( z, "uname", ( char* )pAccount -> getUname( ), 1 );
420 add_assoc_string( z, "name", ( char* )pAccount -> getName( ), 1 );
421 add_assoc_string( z, "email", ( char* )pAccount -> getEmail( ), 1 );
422 add_assoc_string( z, "url", ( char* )pAccount -> getURL( ), 1 );
423 add_assoc_string( z, "user_avatar", ( char* )pAccount -> getUserAvatar( ), 1 );
424 add_assoc_string( z, "user_icq", ( char* )pAccount -> getUserIcq( ), 1 );
425 add_assoc_string( z, "user_from", ( char* )pAccount -> getUserFrom( ), 1 );
426 add_assoc_string( z, "user_sig", ( char* )pAccount -> getUserSig( ), 1 );
427 add_assoc_string( z, "actkey", ( char* )pAccount -> getActkey( ), 1 );
428 add_assoc_string( z, "user_aim", ( char* )pAccount -> getUserAim( ), 1 );
429 add_assoc_string( z, "user_yim", ( char* )pAccount -> getUserYim( ), 1 );
430 add_assoc_string( z, "user_msnm", ( char* )pAccount -> getUserMsnm( ), 1 );
431 add_assoc_string( z, "pass", ( char* )pAccount -> getPass( ), 1 );
432 add_assoc_string( z, "theme", ( char* )pAccount -> getTheme( ), 1 );
433 add_assoc_string( z, "umode", ( char* )pAccount -> getUmode( ), 1 );
434 add_assoc_string( z, "user_occ", ( char* )pAccount -> getUserOcc( ), 1 );
435 add_assoc_string( z, "bio", ( char* )pAccount -> getBio( ), 1 );
436 add_assoc_string( z, "user_intrest", ( char* )pAccount -> getUserIntrest( ), 1 );
437 add_assoc_double( z, "timezone_offset", pAccount -> getTimezoneOffset( ) );
438 add_assoc_long( z, "attachsig", pAccount -> getAttachsig( ) );
439 add_assoc_long( z, "last_login", pAccount -> getLastLogin( ) );
440 add_assoc_long( z, "level", pAccount -> getLevel( ) );
441 add_assoc_long( z, "notify_method", pAccount -> getNotifyMethod( ) );
442 add_assoc_long( z, "notify_mode", pAccount -> getNotifyMode( ) );
443 add_assoc_long( z, "posts", pAccount -> getPosts( ) );
444 add_assoc_long( z, "rank", pAccount -> getRank( ) );
445 add_assoc_long( z, "uorder", pAccount -> getUorder( ) );
446 add_assoc_long( z, "user_mailok", pAccount -> getUserMailok( ) );
447 add_assoc_long( z, "user_regdate", pAccount -> getUserRegdate( ) );
448 add_assoc_long( z, "user_viewemail", pAccount -> getUserViewemail( ) );
449
450 add_assoc_long( z, "activate", pAccount -> getActivate( ) );
451 add_assoc_string( z, "address", ( char* )pAccount -> getAddress( ), 1 );
452 add_assoc_string( z, "institute", ( char* )pAccount -> getInstitute( ), 1 );
453 add_assoc_string( z, "tel", ( char* )pAccount -> getTel( ), 1 );
454 add_assoc_string( z, "organization", ( char* )pAccount -> getOrganization( ), 1 );
455 add_assoc_string( z, "country", ( char* )pAccount -> getCountry( ), 1 );
456 add_assoc_string( z, "zipcode", ( char* )pAccount -> getZipcode( ), 1 );
457 add_assoc_string( z, "fax", ( char* )pAccount -> getFax( ), 1 );
458 add_assoc_string( z, "base_url", ( char* )pAccount -> getBaseURL( ), 1 );
459 add_assoc_long( z, "notice_mail", pAccount -> getNoticeMail( ) );
460 add_assoc_long( z, "notice_mail_since", pAccount -> getNoticeMailSince( ) );
461 return RES_OK;
462 }
463
464 /** accounts ?? zval
465 * accounts: ????????????????
466 array(
467 array(
468 'uid'=>100,
469 'activate'=>1,
470 'institute'=>'foo',
471 'tel'=>'123-456-789',
472 ...
473 ),
474 ...
475 )
476 */
477 result_t accountsToZval( const account_t *pAccounts, int accountsLen, zval *z )
478 {
479 zend_hash_clean( z -> value.ht );
480 for( int i = 0; i < accountsLen; i++ ){
481 zval *new_array;
482 MAKE_STD_ZVAL(new_array);
483 if(array_init(new_array) != SUCCESS){
484 return RES_ERROR;
485 }
486 add_index_zval( z, i, new_array );
487 accountToZval( &pAccounts[ i ], new_array );
488 }
489 return RES_OK;
490 }
491
492 /** groups ?? zval
493 */
494 result_t groupsToZval( const group_t *pGroups, int groupsLen, zval *z )
495 {
496 zend_hash_clean( z -> value.ht );
497 for( int i = 0; i < groupsLen; i++ ){
498 zval *new_array;
499 MAKE_STD_ZVAL(new_array);
500 if(array_init(new_array) != SUCCESS){
501 return RES_ERROR;
502 }
503 add_index_zval( z, i, new_array );
504 add_assoc_long( new_array, "gid", pGroups[ i ].getGID( ) );
505 add_assoc_string( new_array, "gname", ( char* )pGroups[ i ].getGname( ), 1 );
506 add_assoc_string( new_array, "gdesc", ( char* )pGroups[ i ].getDesc( ), 1 );
507 }
508 return RES_OK;
509 }
510
511 /**
512 *
513 * group_t????絎鴻??PHP???f?渇?????????????
514 *
515 * @param pGroup 紊??????????違???若??????/span>
516 * @param z 紊???腟??????吾??莨若???f?渇????(??????羝??帥?с????????
517 * @return RES_OK
518 *
519 */
520 result_t groupToZval( const group_t *pGroup, zval *z )
521 {
522 zend_hash_clean( z -> value.ht );
523 add_assoc_long( z, "gid", pGroup -> getGID( ) );
524 add_assoc_string( z, "gname", ( char* )pGroup -> getGname( ), 1 );
525 add_assoc_string( z, "gdesc", ( char* )pGroup -> getDesc( ), 1 );
526 return RES_OK;
527 }
528
529 /** zval ?? group
530 */
531 result_t zvalToGroup( zval *z, group_t *pGroup )
532 {
533 zval **tmp;
534 HashPosition pos;
535 int i = 0;
536 char* key = 0;
537
538 key = "gid";
539 zend_hash_find( z -> value.ht, key, strlen( key ) + 1, ( void** )&tmp );
540 convert_to_long_ex( tmp ) ;
541 pGroup -> setGID( (*tmp) -> value.lval );
542
543 key = "gname";
544 zend_hash_find( z -> value.ht, key, strlen( key ) + 1, ( void** )&tmp );
545 convert_to_string_ex( tmp ) ;
546 pGroup -> setGname( (*tmp) -> value.str.val );
547
548 key = "gdesc";
549 zend_hash_find( z -> value.ht, key, strlen( key ) + 1, ( void** )&tmp );
550 convert_to_string_ex( tmp ) ;
551 pGroup -> setDesc( (*tmp) -> value.str.val );
552
553 return RES_OK;
554 }
555
556
557 // int vp_get_group( int sid, int gid, array group );
558 ZEND_FUNCTION(vp_get_group)
559 {
560 long sid, gid;
561 zval *zgroup;
562
563 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lla",
564 &sid, &gid, &zgroup) == FAILURE) {
565 return;
566 }
567
568 const group_t *pgroup;
569 result_t result = getGroup( (sessionid_t)sid, (groupid_t)gid, &pgroup );
570 if ( RES_OK == result ){
571 groupToZval( pgroup, zgroup );
572 freeResult( pgroup );
573 }
574
575 RETURN_LONG(result);
576 }
577
578
579 // int vp_get_groups( int sid, array gids, array criteria, array groups );
580 ZEND_FUNCTION(vp_get_groups)
581 {
582 result_t result;
583 long sid, uid;
584 zval *zcriteria;
585 zval *zgids;
586 zval *zgroups;
587 zval **ppzTmp = 0;
588 HashPosition pos;
589 int res2;
590 int gidsLen;
591 const group_t* groups;
592 int groupsLen;
593
594 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "laaa",
595 &sid, &zgids, &zcriteria, &zgroups) == FAILURE) {
596 return;
597 }
598
599 //gids???違???若??ID???潟???若????
600 gidsLen = zend_hash_num_elements(Z_ARRVAL_P(zgids));
601 groupid_t *gids = new groupid_t[ gidsLen ];
602 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(zgids), &pos);
603 for( int i = 0; i < gidsLen; i++ ){
604 if( (res2=zend_hash_get_current_data_ex(Z_ARRVAL_P(zgids), (void **)&ppzTmp, &pos)) == SUCCESS ){
605 SEPARATE_ZVAL(ppzTmp);
606 convert_to_long_ex(ppzTmp);
607 gids[ i ] = Z_LVAL_PP(ppzTmp);
608 }
609 zend_hash_move_forward_ex(Z_ARRVAL_P(zgids), &pos);
610 }
611
612 zCriteria_t zcri(zcriteria);
613 result = zcri.getResult();
614 if ( RES_OK == result ){
615 result = getGroups( (sessionid_t)sid, gids, gidsLen, &zcri, &groups, &groupsLen );
616 if ( RES_OK == result ){
617 delete[] gids;
618 freeResult( groups );
619 }
620 }
621 groupsToZval( groups, groupsLen, zgroups );
622 RETURN_LONG(result);
623 }
624
625
626 // int vp_is_moderator(string uname)
627 ZEND_FUNCTION(vp_is_moderator)
628 {
629 long vpSessionID;
630 userid_t uid;
631
632 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll",
633 &vpSessionID, &uid) == FAILURE) {
634 return;
635 }
636
637 bool result = isModerator( (sessionid_t)vpSessionID, uid );
638 RETURN_BOOL(result)
639 }
640
641 // int vp_get_uid(string uname)
642 ZEND_FUNCTION(vp_get_uid)
643 {
644 char *uname;
645 int unameLen;
646 userid_t uid;
647
648 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
649 &uname, &unameLen) == FAILURE) {
650 return;
651 }
652
653 string strUname( uname, unameLen );
654 result_t result = getUid( strUname.c_str(), &uid );
655 if ( result == RES_OK ){
656 RETURN_LONG((long)uid);
657 }
658 else {
659 //zend_printf( "vpal_debug: vp_get_uid(%s): result=%d<br>\n", strUname.c_str(),(int)result );
660 RETURN_FALSE
661 }
662 }
663
664 /** session ?? zval
665 */
666 result_t sessionToZval( const session_t *pSession, zval *z )
667 {
668 string sessionID(unsignedIntToString(pSession->getSessionID()));
669 add_assoc_string(z, "session_id", (char *)sessionID.c_str(), 1);
670
671 string date(unsignedIntToString((unsigned int)pSession->getDate()));
672 add_assoc_string(z, "date", (char *)date.c_str(), 1);
673
674 string userID(unsignedIntToString((unsigned int)pSession->getUserID()));
675 add_assoc_string(z, "user_id", (char *)userID.c_str(), 1);
676
677 return RES_OK;
678 }
679
680 ZEND_FUNCTION(vp_test_criteria)
681 {
682 zval *z;
683
684 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a",
685 &z) == FAILURE) {
686 return;
687 }
688 zend_printf("zend_printf...<br>\n");
689 zCriteria_t zcri(z);
690 zcri.dump();
691 RETURN_FALSE
692 }
693
694 ZEND_FUNCTION(vp_test_uids)
695 {
696 zval *z;
697
698 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a",
699 &z) == FAILURE) {
700 return;
701 }
702 zend_printf("zend_printf...<br>\n");
703 zUIDs_t zuids(z);
704 zuids.dump();
705 RETURN_FALSE
706 }
707
708
709
710 /** DB??・膓????????≪??・膓?筝???・膓???????????????<br>
711 int initialize_db( string host[, string user[, string password[, string dbname[, string prefix]]]] );
712 @param host ?ョ????????ユ????ULL
713 @param user DB?ョ????????若?九???????ユ????ULL
714 @param password DB?ョ????????鴻???若???????ユ????ULL
715 @param dbname DB?ョ?????B???????ユ????quot;"
716 @param prefix XOOPS DB ??refix??
717 @return 0 success <br>
718 */
719 ZEND_FUNCTION(vp_initialize_db)
720 {
721 zval **parameters[5];
722 char *host;
723 char *user;
724 char *password;
725 char *dbname;
726 char *prefix;
727
728 /* get the number of arguments */
729 int argNum = ZEND_NUM_ARGS();
730 if (argNum > 5)
731 WRONG_PARAM_COUNT;
732
733 /* argument count is correct, now retrieve arguments */
734 if(zend_get_parameters_array_ex(argNum, parameters) != SUCCESS)
735 WRONG_PARAM_COUNT;
736
737 if (argNum < 1) host = NULL;
738 else host = getZvalString( parameters[0] );
739
740 if (argNum < 2) user = NULL;
741 else user = getZvalString( parameters[1] );
742
743 if (argNum < 3) password = NULL;
744 else password = getZvalString( parameters[2] );
745
746 if (argNum < 4) dbname = "";
747 else dbname = getZvalString( parameters[3] );
748
749 if (argNum < 5) prefix = "";
750 else prefix = getZvalString( parameters[4] );
751
752 result_t result = initializeDB( host, user, password, dbname, prefix );
753
754 RETURN_LONG(result);
755 }
756
757 /** ???違?ゃ?潟??????<br>
758 int vp_login_user(string uname, string password)
759 @param uname ???若?九??(xoops_users.uname)
760 @param password ???鴻???若??(md5(password)=xoops_users.pass)
761 @return 0 success
762 */
763 ZEND_FUNCTION(vp_login_user)
764 {
765 char *uname;
766 int unameLen;
767 char *passwd;
768 int passwdLen;
769
770 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
771 &uname, &unameLen, &passwd, &passwdLen) == FAILURE) {
772 return;
773 }
774
775 sessionid_t vpSessionID;
776 result_t result = loginUser( uname, passwd, &vpSessionID );
777 if ( result == RES_OK ){
778 RETURN_LONG((long)vpSessionID);
779 }
780 else {
781 //zend_printf( "vpal_debug: vp_login_user(%s, %s): cannot login. result=%d<br>\n", strUname.c_str(), strPasswd.c_str(), (int)result );
782 RETURN_FALSE
783 }
784 }
785
786 /** ???違?≪??????????<br>
787 void vp_logout_user(int vp_session_id)
788 @param vp_session_id vp??essionid
789 @return ????
790 */
791 ZEND_FUNCTION(vp_logout_user)
792 {
793 long vpSessionID;
794
795 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &vpSessionID) == FAILURE) {
796 return;
797 }
798 logoutUser( (sessionid_t)vpSessionID );
799
800 RETURN_NULL();
801 }
802
803 /** vp ? session id 篏???<br>
804 int vp_create_session( string xoops_sess_id, int uid, string remote_host )
805 @param xoops_sess_id xoops??ession id
806 @param uid xoops ? uid (xoops_users.uid)
807 @return FALSE篁ュ?: vp ? session id
808 @return FALSE: 紊掩??
809 */
810 ZEND_FUNCTION(vp_create_session)
811 {
812 char *xoopsSessionID;
813 int xoopsSessionIDLen;
814 long uid;
815
816 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl",
817 &xoopsSessionID, &xoopsSessionIDLen, &uid) == FAILURE) {
818 return;
819 }
820
821 sessionid_t vpSessionID = 0;
822 result_t result = createSession( xoopsSessionID, (userid_t)uid, &vpSessionID );
823 if ( result == RES_OK ){
824 RETURN_LONG((long)vpSessionID);
825 }
826 else {
827 RETURN_FALSE;
828 }
829 }
830
831 /** vp ? session ???膣井???宴??緇???<br>
832 int vp_get_session( int vp_session_id, array session_info )
833 @param vp_session_id vp ? session id
834 @param session_info 腟?????????????????
835 @return 0 success
836 */
837 ZEND_FUNCTION(vp_get_session)
838 {
839 long vpSessionID;
840 zval *sessionInfo;
841 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "la",
842 &vpSessionID, &sessionInfo) == FAILURE) {
843 return;
844 }
845 const session_t *session = 0;
846 result_t result = getSession( (sessionid_t)vpSessionID, &session );
847 if ( result == RES_OK ){
848 sessionToZval( session, sessionInfo );
849 freeResult( session );
850 }
851
852 RETURN_LONG((long)result);
853 }
854
855 /** activate?倶?? ??緇?<br>
856 bool vp_is_activated( int vp_session_id, int user_id )
857 @param vp_session_id vp ? session id
858 @param user_id xoops_users.uid
859 @return 0 success
860 */
861 ZEND_FUNCTION(vp_is_activated)
862 {
863 long sid, uid;
864
865 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &sid, &uid) == FAILURE) {
866 return;
867 }
868
869 bool result = isActivated( (sessionid_t)sid, (userid_t)uid );
870
871 RETURN_BOOL(result);
872 }
873
874 /** activate??????<br>
875 bool vp_activate( int vp_session_id, bool activated )
876 @param vp_session_id vp ? session id
877 @param user_id xoops_users.uid
878 @param activated true:activate, false:inactivate
879 @return 0 success
880 */
881 ZEND_FUNCTION(vp_activate)
882 {
883 long sid, uid;
884 bool activated;
885
886 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "llb",
887 &sid, &uid, &activated) == FAILURE) {
888 return;
889 }
890
891 result_t result = activate( (sessionid_t)sid, (userid_t)uid, activated );
892
893 RETURN_LONG(result);
894 }
895
896 /** vp???≪?????潟???違??緇?????<br>
897 int vp_get_account_count( int vp_session_id )
898 @param vp_session_id vp ? session id
899 @return 0 success
900 */
901 ZEND_FUNCTION(vp_get_account_count)
902 {
903 long sid;
904
905 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
906 &sid) == FAILURE) {
907 return;
908 }
909
910 long count = getAccountCount( (sessionid_t)sid );
911
912 RETURN_LONG(count);
913 }
914
915 /** ?≪?????潟???????ゃ??????<br>
916 bool vp_delete_account( int vp_session_id, int user_id )
917 @param vp_session_id vp ? session id
918 @param user_id xoops_users.uid
919 @return 0 success
920 */
921 ZEND_FUNCTION(vp_delete_account)
922 {
923 long sid, uid;
924
925 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll",
926 &sid, &uid) == FAILURE) {
927 return;
928 }
929
930 result_t result = deleteAccount( (sessionid_t)sid, (userid_t)uid );
931
932 RETURN_LONG(result);
933 }
934
935 /** ?≪?????潟?????宴??緇?????<br>
936 int vp_get_account( int vp_session_id, int user_id, array account_info )
937 @param vp_session_id vp ? session id
938 @param user_id xoops_users.uid
939 @param account_info ?≪?????潟?????宴???????????f?渇????
940 @return 0 success
941 */
942 ZEND_FUNCTION(vp_get_account)
943 {
944 long sid, uid;
945 zval *zaccount;
946
947 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lla",
948 &sid, &uid, &zaccount) == FAILURE) {
949 fprintf( stderr, "error occured " );
950 return;
951 }
952
953 const account_t *paccount;
954 result_t result = getAccount( (sessionid_t)sid, (userid_t)uid, &paccount );
955 if ( RES_OK == result ){
956 accountToZval( paccount, zaccount );
957 freeResult( paccount );
958 }
959
960 RETURN_LONG(result);
961 }
962
963 /** ?>散????眼?????≪?????潟???????宴??緇?????<br>
964 int vp_get_accoutns( int sid, array uids, array criteria, array accounts );
965 @param vp_session_id vp ? session id
966 @param user_id xoops_users.uid
967 @param criteria ??緇?膀??蚊?祉?純?若??????茵???????
968 @param account_info ?≪?????潟?????宴???????????f?渇????
969 @return 0 success
970 */
971 ZEND_FUNCTION(vp_get_accounts)
972 {
973 result_t result;
974 long sid;
975 zval *zuids;
976 zval *zcriteria;
977 zval *zaccount;
978
979 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "laaa",
980 &sid, &zuids, &zcriteria, &zaccount) == FAILURE) {
981 return;
982 }
983
984 zCriteria_t zcri(zcriteria);
985 result = zcri.getResult();
986 if ( RES_OK == result ){
987 zUIDs_t zUIDs(zuids);
988 result = zUIDs.getResult();
989 if ( RES_OK == result ){
990 const account_t *paccounts;
991 int accountLen;
992 result = getAccounts( (sessionid_t)sid,
993 zUIDs.getPUID(), zUIDs.getLen(),
994 &zcri, &paccounts, &accountLen );
995 if ( RES_OK == result ){
996 accountsToZval( paccounts, accountLen, zaccount );
997 freeResult( paccounts );
998 }
999 }
1000 }
1001
1002 RETURN_LONG(result);
1003 }
1004
1005 /** ?≪?????潟?????宴??緇?????<br>
1006 int vp_insert_account( int sid, array account_info );
1007 @param vp_session_id vp ? session id
1008 @param user_id xoops_users.uid
1009 @param account_info ?≪?????潟?????宴???????????f?渇????
1010 @return 0 success
1011 */
1012 ZEND_FUNCTION(vp_insert_account)
1013 {
1014 result_t result;
1015 long sid;
1016 zval *zaccount;
1017
1018 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "la",
1019 &sid, &zaccount) == FAILURE) {
1020 return;
1021 }
1022
1023 zAccount_t zacc(zaccount);
1024 result = zacc.getResult();
1025 if ( RES_OK == result ){
1026 result = insertAccount( (sessionid_t)sid, &zacc );
1027 }
1028
1029 RETURN_LONG(result);
1030 }
1031
1032 /** ?≪?????潟?????宴???贋?違??????<br>
1033 int vp_update_account( int sid, array account );
1034 @param vp_session_id vp ? session id
1035 @param account_info ?吾??莨若???鴻???≪?????潟?????宴??茵????f?渇????
1036 @return 0 success
1037 */
1038 ZEND_FUNCTION(vp_update_account)
1039 {
1040 result_t result;
1041 long sid;
1042 zval *zaccount;
1043
1044 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "la",
1045 &sid, &zaccount) == FAILURE) {
1046 return;
1047 }
1048
1049 zAccount_t zacc(zaccount);
1050 result = zacc.getResult();
1051 if ( RES_OK == result ){
1052 result = updateAccount( (sessionid_t)sid, &zacc );
1053 }
1054
1055 RETURN_LONG(result);
1056 }
1057
1058 /** ?>散???????≪?????潟????id???荀с??緇?????<br>
1059 int vp_dump_uids( int vp_session_id, array criteria, array uids );
1060 @param vp_session_id vp ? session id
1061 @param criteria ??緇?膀??蚊?祉?純?若??????茵???????
1062 @param uids uid??????????????
1063 @return 0 success
1064 */
1065 ZEND_FUNCTION(vp_dump_uids)
1066 {
1067 result_t result;
1068 long sid;
1069 zval *zcriteria;
1070 zval *zuids;
1071
1072 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "laa",
1073 &sid, &zcriteria, &zuids) == FAILURE) {
1074 return;
1075 }
1076
1077 zCriteria_t zcri(zcriteria);
1078 result = zcri.getResult();
1079 if ( RES_OK == result ){
1080 userid_t *puid;
1081 int uidLen;
1082 result = dumpUids( (sessionid_t)sid, &zcri, &puid, &uidLen );
1083 if ( RES_OK == result ){
1084 uidsToZval( puid, uidLen, &zuids );
1085 freeResult( puid );
1086 }
1087 }
1088
1089 RETURN_LONG(result);
1090 }
1091
1092 /** VP???違???若?????違??緇???<br>
1093 int vp_get_group_count( int sid );
1094 @param vp_session_id vp ? session id
1095 @return ?違???若????/span>
1096 */
1097 ZEND_FUNCTION(vp_get_group_count)
1098 {
1099 result_t result;
1100 long sid;
1101
1102 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
1103 &sid) == FAILURE) {
1104 return;
1105 }
1106
1107 int count = getGroupCount( (sessionid_t)sid );
1108
1109 RETURN_LONG(count);
1110 }
1111
1112 /** uid?ф??絎????????若?吟??絮????違???若???с?????ゆ?>散????眼?????違???若????id??緇???<br>
1113 int vp_get_group_by_uid( int sid, int uid, array criteria, array gids );
1114 @param vp_session_id vp ? session id
1115 @param user_id xoops_users.uid
1116 @param criteria ??緇?膀??蚊?祉?純?若??????茵???????
1117 @param gids gid??????????????
1118 @return 0 success
1119 */
1120 ZEND_FUNCTION(vp_get_groups_by_uid)
1121 {
1122 result_t result;
1123 long sid, uid;
1124 zval *zcriteria;
1125 zval *zgids;
1126
1127 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "llaa",
1128 &sid, &uid, &zcriteria, &zgids) == FAILURE) {
1129 return;
1130 }
1131
1132 zCriteria_t zcri(zcriteria);
1133 result = zcri.getResult();
1134 if ( RES_OK == result ){
1135 groupid_t *pgids;
1136 int gidLen;
1137 result = getGroupsByUid( (sessionid_t)sid, (userid_t)uid, &zcri, &pgids, &gidLen );
1138 if ( RES_OK == result ){
1139 gidsToZval( pgids, gidLen, &zgids );
1140 freeResult( pgids );
1141 }
1142 }
1143
1144 RETURN_LONG(result);
1145 }
1146
1147
1148
1149 /** uid?ф??絎????????若?吟??gid?ф??絎??????違???若?????違???若??膊∞??????????????緇???<br>
1150 int vp_is_group_admin( int sid, int gid, int uid );
1151 @param vp_session_id vp ? session id
1152 @param group_id VP???違???若??ID
1153 @param user_id xoops_users.uid
1154 @return true: ?違???若??膊∞?????с??????
1155 @return false: ?違???若??膊∞?????с???????????????????若?с??????
1156 */
1157 ZEND_FUNCTION(vp_is_group_admin)
1158 {
1159 result_t result;
1160 long sid, gid, uid;
1161
1162 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll",
1163 &sid, &gid, &uid) == FAILURE) {
1164 return;
1165 }
1166
1167 bool b = isGroupAdmin( (sessionid_t)sid, (groupid_t)gid, (userid_t)uid );
1168
1169 RETURN_BOOL(b);
1170 }
1171
1172 /** ?>散????眼?????違???若????id???荀с??緇?????<br>
1173 int vp_dump_gids( int sid, array criteria, array gids );
1174 @param vp_session_id vp ? session id
1175 @param criteria ??緇?膀??蚊?祉?純?若??????茵???????
1176 @param gids gid??????????????
1177 @return 0 success
1178 */
1179 ZEND_FUNCTION(vp_dump_gids)
1180 {
1181 result_t result;
1182 long sid;
1183 zval *zcriteria;
1184 zval *zgids;
1185
1186 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "laa",
1187 &sid, &zcriteria, &zgids) == FAILURE) {
1188 return;
1189 }
1190
1191 zCriteria_t zcri(zcriteria);
1192 result = zcri.getResult();
1193 if ( RES_OK == result ){
1194 groupid_t *pgid;
1195 int gidLen;
1196 result = dumpGids( (sessionid_t)sid, &zcri, &pgid, &gidLen );
1197 if ( RES_OK == result ){
1198 gidsToZval( pgid, gidLen, &zgids );
1199 freeResult( pgid );
1200 }
1201 }
1202
1203 RETURN_LONG(result);
1204 }
1205
1206 /** gid?ф??絎??????違???若??????????с?????ゆ?>散????眼?????違???若??膊∞??????id???荀с??緇?????<br>
1207 int vp_dump_group_admins(int sid, int group_id, array criteria, array uids )
1208 @param sid ?祉???激?с??D
1209 @param group_id VP?違???若??ID
1210 @param criteria ?>散
1211 @param uids uid???荀с??????????????
1212 @return 0 success
1213 */
1214
1215 ZEND_FUNCTION(vp_dump_group_admins)
1216 {
1217 long sid, gid;
1218 zval *zcriteria;
1219 zval *zuids;
1220
1221 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "llaa",
1222 &sid, &gid, &zcriteria, &zuids) == FAILURE) {
1223 return;
1224 }
1225
1226 zCriteria_t zcri(zcriteria);
1227 result_t result = zcri.getResult();
1228 if ( result == RES_OK ){
1229 userid_t *uids;
1230 int uidsLen;
1231 result = dumpGroupAdmins( sid, gid, &zcri, &uids, &uidsLen );
1232 if ( result == RES_OK ){
1233 uidsToZval( uids, uidsLen, &zuids );
1234 freeResult( uids );
1235 }
1236 }
1237 RETURN_LONG( result );
1238 }
1239
1240
1241 /** ?違???若?????宴??紊??眼??????<br>
1242 int vp_update_group(int sid, array group )
1243 @param sid ?祉???激?с??D
1244 @param group ?違???若?????宴???f?渇????
1245 @return 0 success
1246 */
1247 ZEND_FUNCTION(vp_update_group)
1248 {
1249 long sid;
1250 zval *zgroup;
1251 group_t group;
1252
1253 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "la",
1254 &sid, &zgroup) == FAILURE) {
1255 return;
1256 }
1257
1258 zvalToGroup( zgroup, &group );
1259 result_t result = updateGroup( sid, &group );
1260 RETURN_LONG( result );
1261 }
1262
1263 /** ?????惹??絖?????緇???<br>
1264 string vp_get_last_error_string()
1265 @return 0 success
1266 */
1267 ZEND_FUNCTION(vp_get_last_error_string)
1268 {
1269 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "" ) == FAILURE) {
1270 return;
1271 }
1272
1273 string str( getLastErrorString() );
1274 RETURN_STRING((char *)str.c_str(), 1);
1275 }
1276

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26