zval * activerecord_extract_validate_options( zval * arr ) { zval * retval; MAKE_STD_ZVAL( retval ); array_init( retval ); if( Z_TYPE_P(arr) == IS_ARRAY && zend_hash_num_elements( Z_ARRVAL_P(arr) ) > 0 ) { zval **last; char *key; int key_len, j; zend_hash_internal_pointer_end(Z_ARRVAL_P(arr)); zend_hash_get_current_data(Z_ARRVAL_P(arr), (void **)&last); if( activerecord_is_options_hash(last, 0) ) { retval = last; zend_hash_get_current_key_ex(Z_ARRVAL_P(arr), &key, &key_len, &j, 0, NULL); zend_hash_del_key_or_index(Z_ARRVAL_P(arr), key, key_len, j, (key) ? HASH_DEL_KEY : HASH_DEL_INDEX); if( !key_len && j >= Z_ARRVAL_P(arr)->nNextFreeElement - 1 ) Z_ARRVAL_P(arr)->nNextFreeElement = Z_ARRVAL_P(arr)->nNextFreeElement - 1; zend_hash_internal_pointer_reset(Z_ARRVAL_P(arr)); } else { if( !activerecord_is_hash(last) ) /* throw exception */; zend_hash_add( Z_ARRVAL_P(retval), "conditions", 10, last, sizeof(zval*), NULL ); } } return retval; }
/* {{{ proto Util::array_last(array $arr) Return the last value from an array. */ ZEND_METHOD(util, array_last) { zval *arr, **zvalue; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) { RETURN_NULL(); } if (Z_TYPE_P(arr) != IS_ARRAY) { RETURN_NULL(); } zend_hash_internal_pointer_end(Z_ARRVAL_P(arr)); if (zend_hash_get_current_data(Z_ARRVAL_P(arr), (void**)&zvalue) == FAILURE) { RETURN_NULL(); } *return_value = **zvalue; zval_copy_ctor(return_value); return; }
/* {{{ proto Util::array_last_key(array $array) Return the last key from an array. */ ZEND_METHOD(util, array_last_key) { char *key; uint keylen; ulong idx; zval *arr; int type; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &arr) == FAILURE) { RETURN_NULL(); } if (Z_TYPE_P(arr) != IS_ARRAY) { RETURN_NULL(); } zend_hash_internal_pointer_end(Z_ARRVAL_P(arr)); type = zend_hash_get_current_key_ex(Z_ARRVAL_P(arr), &key, &keylen, &idx, 0, NULL); if (type == HASH_KEY_IS_STRING) { RETURN_STRINGL(key, keylen, 0); } else if (type == HASH_KEY_IS_LONG) { RETURN_LONG(idx); } RETURN_NULL(); }