<?php

class crf_field_repeater extends acf_field {

    var $settings;

    /*
     *  __construct
     *
     *  Set name / label needed for actions / filters
     *
     *  @since	3.6
     *  @date	23/01/13
     */

    function __construct() {
        // vars
        $this->name = 'repeater';
        $this->label = __("Repeater", 'acf');
        $this->category = __("Layout", 'acf');
        $this->defaults = array(
            'sub_fields' => array(),
            'row_min' => 0,
            'row_limit' => 0,
            'layout' => 'table',
            'button_label' => __("Add Row", 'acf'),
        );
        $this->l10n = array(
            'min' => __("Minimum rows reached ( {min} rows )", 'acf'),
            'max' => __("Maximum rows reached ( {max} rows )", 'acf'),
        );


        // do not delete!
        parent::__construct();


        // settings
        $this->settings = array(
            'path' => apply_filters('acf/helpers/get_path', __FILE__),
            'dir' => apply_filters('acf/helpers/get_dir', __FILE__),
            'version' => '1.0'
        );
    }

    /*
     *  input_admin_enqueue_scripts()
     *
     *  This action is called in the admin_enqueue_scripts action on the edit screen where your field is created.
     *  Use this action to add css + javascript to assist your create_field() action.
     *
     *  $info	http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts
     *  @type	action
     *  @since	3.6
     *  @date	23/01/13
     */

    function input_admin_enqueue_scripts() {
        // register crf scripts
        wp_register_script('crf-input-repeater', $this->settings['dir'] . 'js/input.js', array('acf-input'), $this->settings['version']);
        wp_register_style('crf-input-repeater', $this->settings['dir'] . 'css/input.css', array('acf-input'), $this->settings['version']);


        // scripts
        wp_enqueue_script(array(
            'crf-input-repeater',
        ));

        // styles
        wp_enqueue_style(array(
            'crf-input-repeater',
        ));
    }

    /*
     *  field_group_admin_enqueue_scripts()
     *
     *  This action is called in the admin_enqueue_scripts action on the edit screen where your field is edited.
     *  Use this action to add css + javascript to assist your create_field_options() action.
     *
     *  $info	http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts
     *  @type	action
     *  @since	3.6
     *  @date	23/01/13
     */

    function field_group_admin_enqueue_scripts() {
        wp_register_script('crf-field-group-repeater', $this->settings['dir'] . 'js/field-group.js', array('acf-field-group'), $this->settings['version']);

        // scripts
        wp_enqueue_script(array(
            'crf-field-group-repeater',
        ));
    }

    /*
     *  load_field()
     *
     *  This filter is appied to the $field after it is loaded from the database
     *
     *  @type	filter
     *  @since	3.6
     *  @date	23/01/13
     *
     *  @param	$field - the field array holding all the field options
     *
     *  @return	$field - the field array holding all the field options
     */

    function load_field($field) {
        // apply_load field to all sub fields
        if (isset($field['sub_fields']) && is_array($field['sub_fields'])) {
            foreach ($field['sub_fields'] as $k => $sub_field) {
                // apply filters
                $sub_field = apply_filters('acf/load_field_defaults', $sub_field);


                // apply filters
                foreach (array('type', 'name', 'key') as $key) {
                    // run filters
                    $sub_field = apply_filters('acf/load_field/' . $key . '=' . $sub_field[$key], $sub_field); // new filter
                }


                // update sub field
                $field['sub_fields'][$k] = $sub_field;
            }
        }


        // return
        return $field;
    }

    /*
     *  create_field()
     *
     *  Create the HTML interface for your field
     *
     *  @param	$field - an array holding all the field's data
     *
     *  @type	action
     *  @since	3.6
     *  @date	23/01/13
     */

    function create_field($field) {
        include( $this->settings['path'] . 'views/field.php' );
    }

    /*
     *  create_options()
     *
     *  Create extra options for your field. This is rendered when editing a field.
     *  The value of $field['name'] can be used (like bellow) to save extra data to the $field
     *
     *  @type	action
     *  @since	3.6
     *  @date	23/01/13
     *
     *  @param	$field	- an array holding all the field's data
     */

    function create_options($field) {
        include( $this->settings['path'] . 'views/options.php' );
    }

    /*
     *  update_value()
     *
     *  This filter is appied to the $value before it is updated in the db
     *
     *  @type	filter
     *  @since	3.6
     *  @date	23/01/13
     *
     *  @param	$value - the value which will be saved in the database
     *  @param	$field - the field array holding all the field options
     *  @param	$post_id - the $post_id of which the value will be saved
     *
     *  @return	$value - the modified value
     */

    function update_value($value, $post_id, $field) {
        $total = 0;

        if ($value) {
            // remove dummy field
            unset($value['acfcloneindex']);

            $i = -1;

            // loop through rows
            foreach ($value as $row) {
                $i++;

                // increase total
                $total++;

                // loop through sub fields
                foreach ($field['sub_fields'] as $sub_field) {
                    // get sub field data
                    $v = isset($row[$sub_field['key']]) ? $row[$sub_field['key']] : false;

                    // update full name
                    $sub_field['name'] = $field['name'] . '_' . $i . '_' . $sub_field['name'];

                    // save sub field value
                    do_action('acf/update_value', $v, $post_id, $sub_field);
                }
            }
        }


        /*
         *  Remove Old Data
         *
         *  @credit: http://support.advancedcustomfields.com/discussion/1994/deleting-single-repeater-fields-does-not-remove-entry-from-database
         */


        $old_total = (int) apply_filters('acf/load_value', 0, $post_id, $field);

        if ($old_total > $total) {
            for ($j = $total; $j < $old_total; $j++) {
                foreach ($field['sub_fields'] as $sub_field) {
                    do_action('acf/delete_value', $post_id, $field['name'] . '_' . $j . '_' . $sub_field['name']);
                }
            }
        }




        // update $value and return to allow for the normal save function to run
        $value = $total;


        return $value;
    }

    /*
     *  update_field()
     *
     *  This filter is appied to the $field before it is saved to the database
     *
     *  @type	filter
     *  @since	3.6
     *  @date	23/01/13
     *
     *  @param	$field - the field array holding all the field options
     *  @param	$post_id - the field group ID (post_type = acf)
     *
     *  @return	$field - the modified field
     */

    function update_field($field, $post_id) {
        // format sub_fields
        if ($field['sub_fields']) {
            // remove dummy field
            unset($field['sub_fields']['field_clone']);


            // loop through and save fields
            $i = -1;
            $sub_fields = array();


            foreach ($field['sub_fields'] as $key => $f) {
                $i++;


                // order
                $f['order_no'] = $i;
                $f['key'] = $key;


                // save
                $f = apply_filters('acf/update_field/type=' . $f['type'], $f, $post_id); // new filter
                // add
                $sub_fields[] = $f;
            }


            // update sub fields
            $field['sub_fields'] = $sub_fields;
        }


        // return updated repeater field
        return $field;
    }

    /*
     *  format_value()
     *
     *  This filter is appied to the $value after it is loaded from the db and before it is passed to the create_field action
     *
     *  @type	filter
     *  @since	3.6
     *  @date	23/01/13
     *
     *  @param	$value	- the value which was loaded from the database
     *  @param	$post_id - the $post_id from which the value was loaded
     *  @param	$field	- the field array holding all the field options
     *
     *  @return	$value	- the modified value
     */

    function format_value($value, $post_id, $field) {
        // vars
        $values = array();


        if ($value > 0) {
            // loop through rows
            for ($i = 0; $i < $value; $i++) {
                // loop through sub fields
                foreach ($field['sub_fields'] as $sub_field) {
                    // update full name
                    $key = $sub_field['key'];
                    $sub_field['name'] = $field['name'] . '_' . $i . '_' . $sub_field['name'];

                    $v = apply_filters('acf/load_value', false, $post_id, $sub_field);
                    $v = apply_filters('acf/format_value', $v, $post_id, $sub_field);

                    $values[$i][$key] = $v;
                }
            }
        }


        // return
        return $values;
    }

    /*
     *  format_value_for_api()
     *
     *  This filter is appied to the $value after it is loaded from the db and before it is passed back to the api functions such as the_field
     *
     *  @type	filter
     *  @since	3.6
     *  @date	23/01/13
     *
     *  @param	$value	- the value which was loaded from the database
     *  @param	$post_id - the $post_id from which the value was loaded
     *  @param	$field	- the field array holding all the field options
     *
     *  @return	$value	- the modified value
     */

    function format_value_for_api($value, $post_id, $field) {
        // vars
        $values = array();


        if ($value > 0) {
            // loop through rows
            for ($i = 0; $i < $value; $i++) {
                // loop through sub fields
                foreach ($field['sub_fields'] as $sub_field) {
                    // update full name
                    $key = $sub_field['name'];
                    $sub_field['name'] = $field['name'] . '_' . $i . '_' . $sub_field['name'];

                    $v = apply_filters('acf/load_value', false, $post_id, $sub_field);
                    $v = apply_filters('acf/format_value_for_api', $v, $post_id, $sub_field);

                    $values[$i][$key] = $v;
                }
            }
        }


        // return
        return $values;
    }

}

new crf_field_repeater();
?>
