Example #1
0
/**
 *	parse a string containing html elements
 *
 *	this function decodes html's special characters except for the content 
 *	(when it too is not being parsed).
 *	this function is more fragile than html_parse_elem() when it comes to 
 *	malformatted input.
 *	@param string $html input string
 *	@param bool $recursive also parse children elements
 *	@return array parsed representation
 */
function html_parse($html, $recursive = false)
{
    global $single_tags;
    // from html.inc.php
    $ret = array();
    $pos = 0;
    $open_tag = false;
    $open_pos = false;
    // can probably be done with -1 and some slightly easier code below
    $close_pos = false;
    $num_open = 0;
    while ($pos < strlen($html)) {
        if ($html[$pos] == '<') {
            if (($next = strpos($html, '>', $pos + 1)) === false) {
                // error: unclosed <
                $pos++;
                continue;
            }
            // handle uppercase tags as well
            $tag = strtolower(trim(substr($html, $pos + 1, $next - $pos - 1)));
            if (substr($tag, 0, 1) !== '/') {
                // opening tag
                if ($num_open == 0) {
                    $a = expl_whitesp($tag, true);
                    $open_tag = $a[0];
                    $open_pos = $pos;
                }
                // handle single tags
                if (in_array($tag, $single_tags)) {
                    if ($num_open == 0) {
                        // check if there was something between the last $close_pos and $open_pos
                        $text = '';
                        if ($close_pos === false && 0 < $open_pos) {
                            $text = trim(substr($html, 0, $open_pos));
                        } elseif ($close_pos !== false && $close_pos + 1 < $open_pos) {
                            $text = trim(substr($html, $close_pos + 1, $open_pos - $close_pos - 1));
                        }
                        if (0 < strlen($text)) {
                            $ret[] = $text;
                        }
                        $close_pos = $next;
                        $ret[] = html_parse_elem(substr($html, $open_pos, $close_pos - $open_pos + 1), $recursive);
                    }
                } else {
                    $num_open++;
                }
            } else {
                // closing tag
                $num_open--;
                if ($num_open == 0) {
                    // check if opening and closing tag match
                    if ($open_tag != substr($tag, 1)) {
                        // error: opening and closing tag do not match
                        $pos++;
                        continue;
                    }
                    // check if there was something between the last $close_pos and $open_pos
                    $text = '';
                    if ($close_pos === false && 0 < $open_pos) {
                        $text = trim(substr($html, 0, $open_pos));
                    } elseif ($close_pos !== false && $close_pos + 1 < $open_pos) {
                        $text = trim(substr($html, $close_pos + 1, $open_pos - $close_pos - 1));
                    }
                    if (0 < strlen($text)) {
                        $ret[] = $text;
                    }
                    $close_pos = $next;
                    $ret[] = html_parse_elem(substr($html, $open_pos, $close_pos - $open_pos + 1), $recursive);
                }
            }
        }
        $pos++;
    }
    // check if there was something after the last $close_pos
    $text = '';
    if ($close_pos === false && 1 < $pos) {
        $text = trim($html);
    } elseif ($close_pos !== false && $close_pos + 1 < $pos) {
        $text = trim(substr($html, $close_pos + 1));
    }
    if (0 < strlen($text)) {
        $ret[] = $text;
    }
    return $ret;
}
Example #2
0
/**
 *	save the state of a html element corresponding to an object to disk
 *
 *	this function takes the object lock.
 *	@param array $args arguments
 *		key 'html' one html element
 *	@return array response
 *		true if successful
 */
function save_state($args)
{
    if (empty($args['html'])) {
        return response('Required argument "html" missing or empty', 400);
    }
    require_once 'html.inc.php';
    require_once 'html_parse.inc.php';
    $elem = html_parse_elem($args['html']);
    if (!elem_has_class($elem, 'object')) {
        return response('Error saving state as class "object" is not set', 400);
    } elseif (!object_exists(elem_attr($elem, 'id'))) {
        return response('Error saving state as object does not exist', 404);
    }
    // LOCK
    $L = _obj_lock(elem_attr($elem, 'id'), LOCK_TIME);
    if ($L === false) {
        return response('Could not acquire lock to ' . quot($args['name']) . ' in ' . LOCK_TIME . 'ms', 500);
    }
    $obj = load_object(array('name' => elem_attr($elem, 'id')));
    if ($obj['#error']) {
        // UNLOCK
        _obj_unlock($L);
        return response('Error saving state, cannot load ' . quot(elem_attr($elem, 'id')), 500);
    } else {
        $obj = $obj['#data'];
    }
    $ret = invoke_hook_while('save_state', false, array('elem' => $elem, 'obj' => $obj));
    // UNLOCK
    _obj_unlock($L);
    if (count($ret) == 0) {
        return response('Error saving state as nobody claimed element', 500);
    } else {
        $temp = array_keys($ret);
        log_msg('info', 'save_state: ' . quot($obj['name']) . ' was handled by ' . quot($temp[0]));
        return response(true);
    }
}