[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/libgit2/php-git/old-development/src/commit.c [Back]  [Original]

/*
 * The MIT License
 *
 * Copyright (c) 2010 - 2011 Shuhei Tanuma
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "php_git.h"
#include 
#include 
#include 
#include 

extern void create_tree_entry_from_entry(zval **object, git_tree_entry *entry, git_repository *repository);
extern zend_object_value php_git_repository_new(zend_class_entry *ce TSRMLS_DC);

PHPAPI zend_class_entry *git_commit_class_entry;

ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit__construct, 0, 0, 1)
    ZEND_ARG_INFO(0, repository)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_get_parent, 0, 0, 1)
    ZEND_ARG_INFO(0, offset)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_set_author, 0, 0, 1)
    ZEND_ARG_INFO(0, author)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_set_committer, 0, 0, 1)
    ZEND_ARG_INFO(0, committer)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_set_parents, 0, 0, 1)
    ZEND_ARG_INFO(0, parents)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_set_message, 0, 0, 1)
    ZEND_ARG_INFO(0, message)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_set_tree, 0, 0, 1)
    ZEND_ARG_INFO(0, tree)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_write, 0, 0, 1)
    ZEND_ARG_INFO(0, update_ref)
ZEND_END_ARG_INFO()

static void php_git_commit_free_storage(php_git_commit_t *obj TSRMLS_DC)
{
    zend_object_std_dtor(&obj->zo TSRMLS_CC);
    obj->object = NULL;
    obj->repository = NULL;
    efree(obj);
}

zend_object_value php_git_commit_new(zend_class_entry *ce TSRMLS_DC)
{
    zend_object_value retval;
    php_git_commit_t *obj;
    zval *tmp;

    obj = ecalloc(1, sizeof(*obj));
    zend_object_std_init( &obj->zo, ce TSRMLS_CC );
    zend_hash_copy(obj->zo.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));

    retval.handle = zend_objects_store_put(obj, 
        (zend_objects_store_dtor_t)zend_objects_destroy_object,
        (zend_objects_free_object_storage_t)php_git_commit_free_storage,
        NULL TSRMLS_CC);
    retval.handlers = zend_get_std_object_handlers();
    return retval;
}

PHP_METHOD(git_commit, __construct)
{
    zval *object = getThis();
    zval *z_repository;
    git_commit *commit;
    git_repository *repository;
    int ret;

    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
        "z", &z_repository) == FAILURE){
        return;
    }
    object_init_ex(object, git_commit_class_entry);
    php_git_commit_t *cobj = (php_git_commit_t *) zend_object_store_get_object(object TSRMLS_CC);
    php_git_repository_t *myobj = (php_git_repository_t *) zend_object_store_get_object(z_repository TSRMLS_CC);

    
    cobj->repository = myobj->repository;
}

PHP_METHOD(git_commit, getCommitter)
{
    zval *object = getThis();
    zval *signature = zend_read_property(git_commit_class_entry, object,"committer",9, 0 TSRMLS_CC);

    zval_copy_ctor(signature);
    RETURN_ZVAL(signature,0, 0);
}

PHP_METHOD(git_commit, getMessage)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    const char *message;
    
    message = git_commit_message(this->object);
    RETURN_STRING(message,1);
}

PHP_METHOD(git_commit, getShortMessage)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    const char *message;
    
    message = git_commit_message_short(this->object);
    RETURN_STRING(message,1);
}

PHP_METHOD(git_commit, getTree)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    git_tree *ref_tree, *tree;
    git_oid *tree_oid;
    zval *git_tree, *entry;
    const git_oid *oid;

    git_commit_tree(&ref_tree, this->object);
    oid = git_object_id((git_object*)ref_tree);

    int ret = git_object_lookup((git_object **)&tree, git_object_owner((git_object*)this->object),oid, GIT_OBJ_TREE);
    if(ret != GIT_SUCCESS) {
        php_error_docref(NULL TSRMLS_CC, E_ERROR, "specified tree not found.");
        return;
    }


    MAKE_STD_ZVAL(git_tree);
    object_init_ex(git_tree, git_tree_class_entry);
    php_git_tree_t *tobj = (php_git_tree_t *) zend_object_store_get_object(git_tree TSRMLS_CC);
    tobj->object = tree;
    tobj->repository = this->repository;

    RETURN_ZVAL(git_tree,0,1);
}

PHP_METHOD(git_commit, setAuthor)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    zval *author;

    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
        "z", &author) == FAILURE){
        return;
    }

    if(!instanceof_function(Z_OBJCE_P(author), git_signature_class_entry TSRMLS_CC)){
        fprintf(stderr,"Git\\Commit::setAuthor() requires Git\\Signature");
        return;
    }

    add_property_zval(getThis(),"author", author);
}

PHP_METHOD(git_commit, setCommitter)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    zval *committer;

    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
        "z", &committer) == FAILURE){
        return;
    }

    if(!instanceof_function(Z_OBJCE_P(committer), git_signature_class_entry TSRMLS_CC)){
        fprintf(stderr,"Git\\Commit::setCommitter() requires Git\\Signature");
        return;
    }

    add_property_zval(getThis(),"committer", committer);
}

PHP_METHOD(git_commit, setTree)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    char *tree;
    int tree_len;

    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
        "s", &tree,&tree_len) == FAILURE){
        return;
    }

    add_property_string(getThis(),"tree", tree,1);
}


PHP_METHOD(git_commit, setParents)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    zval *parents;

    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
        "z", &parents) == FAILURE){
        return;
    }

    add_property_zval(getThis(),"parents", parents);
}

PHP_METHOD(git_commit, write)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    git_oid oid, tree_oid, **parents, **p, *tmp;
    php_git_signature_t *author, *committer;
    zval *z_author, *z_committer, *z_parents, **data;
    char *update_ref, *message, *tree_oid_str = NULL;
    char out[GIT_OID_HEXSZ+1];
    int count, i, update_ref_len = 0;
    git_reference *ref;

    HashTable *array_hash;
    HashPosition pointer;

    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
        "|s", &update_ref,&update_ref_len) == FAILURE){
        return;
    }
    
    if(ZEND_NUM_ARGS() == 0) {
        if(git_reference_lookup(&ref,this->repository,"HEAD")==GIT_SUCCESS){
            if (git_reference_type(ref) == GIT_REF_SYMBOLIC) {
                git_reference *ref2;
                git_reference_resolve(&ref2,ref);
                update_ref = (char *)git_reference_name(ref2);
            } else {
                update_ref = (char *)git_reference_name(ref);
            }
        }
    }


    tree_oid_str = Z_STRVAL_P(zend_read_property(git_commit_class_entry, getThis(),"tree",sizeof("tree")-1, 0 TSRMLS_CC));
    git_oid_fromstr(&tree_oid, tree_oid_str);

    z_author = zend_read_property(git_commit_class_entry, getThis(),"author",sizeof("author")-1, 0 TSRMLS_CC);
    author = (php_git_signature_t *) zend_object_store_get_object(z_author TSRMLS_CC);

    z_committer = zend_read_property(git_commit_class_entry, getThis(),"committer",sizeof("committer")-1, 0 TSRMLS_CC);
    committer = (php_git_signature_t *) zend_object_store_get_object(z_committer TSRMLS_CC);
    
    z_parents = zend_read_property(git_commit_class_entry, getThis(),"parents",sizeof("parents")-1, 0 TSRMLS_CC);

    count = zend_hash_num_elements(Z_ARRVAL_P(z_parents));


    array_hash = Z_ARRVAL_P(z_parents);
    parents = (git_oid**)calloc(count,sizeof(git_oid));
    p = parents;

    for (zend_hash_internal_pointer_reset_ex(array_hash, &pointer);
        zend_hash_has_more_elements_ex(array_hash,&pointer) == SUCCESS;
        zend_hash_move_forward_ex(array_hash,&pointer)
    ) {
        tmp = (git_oid *)malloc(sizeof(git_oid));
        zend_hash_get_current_data_ex(array_hash, (void **)&data, &pointer);
        git_oid_fromstr(tmp,Z_STRVAL_PP(data));

        *p = tmp;
        p++;
    }
    
    message = Z_STRVAL_P(zend_read_property(git_commit_class_entry, getThis(),"message",sizeof("message")-1, 0 TSRMLS_CC));
    git_commit_create(&oid,
        this->repository,
        update_ref,
        author->signature,
        committer->signature,
		NULL, // Message encoding (Should probably fix this at some point)
        message,
        &tree_oid,
        count,
        parents
    );

    git_oid_to_string(out,GIT_OID_HEXSZ+1,&oid);

    for(i = 0; i < count;i++){
        free(parents[i]);
    }
    free(parents);

    RETVAL_STRING(out,1);
}

PHP_METHOD(git_commit, setMessage)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    char *message;
    int message_len;

    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
        "s", &message,&message_len) == FAILURE){
        return;
    }

    add_property_string(getThis(),"message", message, 1);
}


PHP_METHOD(git_commit, getAuthor)
{
    zval *object = getThis();
    zval *signature = zend_read_property(git_commit_class_entry, object,"author",6, 0 TSRMLS_CC);

    zval_copy_ctor(signature);
    RETURN_ZVAL(signature,0, 0);
}

PHP_METHOD(git_commit, getParent)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    php_git_commit_t *obj;
    git_commit *commit;
    zval *zcommit;
    int offset = 0;
    int ret = 0;
    zval *author;
    zval *committer;

    if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
        "|l", &offset) == FAILURE){
        return;
    }
    
    ret = git_commit_parent(&commit, this->object,offset);
    if(ret != GIT_SUCCESS){
        //zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "specified offset not found");
        RETURN_FALSE;
    }

    php_git_commit_init(&zcommit, commit, this->repository TSRMLS_CC);

    RETURN_ZVAL(zcommit,0,1);
}

PHP_METHOD(git_commit, getId)
{
    php_git_commit_t *this = (php_git_commit_t *) zend_object_store_get_object(getThis() TSRMLS_CC);
    git_oid *oid = git_commit_id(this->object);
    char id[GIT_OID_HEXSZ+1] = {0};
    
    git_oid_to_string(id,GIT_OID_HEXSZ+1,oid);
    
    RETURN_STRING(id,1);
}

static zend_function_entry php_git_commit_methods[] = {
    PHP_ME(git_commit, __construct,     arginfo_git_commit__construct,   ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, getId,           NULL,                            ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, setAuthor,       arginfo_git_commit_set_author,   ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, setCommitter,    arginfo_git_commit_set_committer,ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, setParents,      arginfo_git_commit_set_parents,  ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, setMessage,      arginfo_git_commit_set_message,  ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, setTree,         arginfo_git_commit_set_tree,     ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, write,           NULL,                            ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, getTree,         NULL,                            ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, getAuthor,       NULL,                            ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, getCommitter,    NULL,                            ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, getMessage,      NULL,                            ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, getShortMessage, NULL,                            ZEND_ACC_PUBLIC)
    PHP_ME(git_commit, getParent,       arginfo_git_commit_get_parent,   ZEND_ACC_PUBLIC)
    {NULL, NULL, NULL}
};

void git_init_commit(TSRMLS_D)
{
    zend_class_entry ce;
    INIT_NS_CLASS_ENTRY(ce, PHP_GIT_NS,"Commit", php_git_commit_methods);
    git_commit_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
    git_commit_class_entry->create_object = php_git_commit_new;

    zend_declare_property_null(git_commit_class_entry, "author",   sizeof("author")-1,    ZEND_ACC_PROTECTED TSRMLS_CC);
    zend_declare_property_null(git_commit_class_entry, "committer",sizeof("committer")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
    zend_declare_property_null(git_commit_class_entry, "parents",  sizeof("parents")-1,   ZEND_ACC_PROTECTED TSRMLS_CC);
    zend_declare_property_null(git_commit_class_entry, "message",  sizeof("message")-1,   ZEND_ACC_PROTECTED TSRMLS_CC);
    zend_declare_property_null(git_commit_class_entry, "tree",     sizeof("tree")-1,      ZEND_ACC_PROTECTED TSRMLS_CC);
}

Web Proxy Viewer  |  New URL  |  Original Page