<?php
/**
 * File containing the ezcDebugPhpStacktraceIterator class.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @package Debug
 * @version //autogentag//
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * Iterator class to wrap around debug_backtrace() stack traces.
 *
 * This iterator class receives a stack trace generated by debug_backtrace()
 * and unifies it as described in the {@link ezcDebugStacktraceIterator}
 * interface.
 * 
 * @package Debug
 * @version //autogen//
 */
class ezcDebugPhpStacktraceIterator extends ezcDebugStacktraceIterator
{
    /**
     * Unifies a stack element for being returned to the formatter.
     *
     * This method ensures that an element of the stack trace conforms to the
     * format expected by a {@link ezcDebugOutputFormatter}. The format is
     * defined as follows:
     *
     * <code>
     * array(
     *      'file'      => '<fullpathtofile>',
     *      'line'      => <lineno>,
     *      'function'  => '<functionname>',
     *      'class'     => '<classname>',
     *      'params'    => array(
     *          <param_no> => '<paramvalueinfo>',
     *          <param_no> => '<paramvalueinfo>',
     *          <param_no> => '<paramvalueinfo>',
     *          ...
     *      )
     * )
     * </code>
     * 
     * @param mixed $stackElement 
     * @return array As described above.
     */
    protected function unifyStackElement( $stackElement )
    {
        // Not to be set in the unified version
        unset( $stackElement['type'] );
        unset( $stackElement['object'] );

        // Unify args -> params
        $stackElement['params'] = $this->convertArgsToParams( $stackElement['args'] );
        unset( $stackElement['args'] );
        
        return $stackElement;
    }

    /**
     * Returns the arguments of a stack element as string dumps.
     *
     * Returns an array corresponding to the 'params' key of a unified stack
     * element, created from the 'args' ($args) element from an unified one.
     * 
     * @param array $args 
     * @return array
     */
    private function convertArgsToParams( $args )
    {
        $params = array();
        foreach ( $args as $arg )
        {
            $params[] = ezcDebugVariableDumpTool::dumpVariable(
                $arg,
                $this->options->stackTraceMaxData,
                $this->options->stackTraceMaxChildren,
                $this->options->stackTraceMaxDepth
            );
        }
        return $params;
    }
}

?>
