Include [meta_data] in an api from Woocommerce order - woocommerce

Hello I have a pluging API that generates a JSON of the seller order list in an object list like. I would like to add the meta data of the order
The code below is the function responsible for the json data :
{
$profile_pic = [];
$api = new WC_REST_Orders_V1_Controller();
$results = [];
if (
is_plugin_active(
"wc-multivendor-marketplace/wc-multivendor-marketplace.php"
)
) {
global $wpdb;
$page = 1;
$per_page = 10;
if (isset($request['page'])) {
$page = sanitize_text_field($request['page']);
if(!is_numeric($page)){
$page = 1;
}
}
if (isset($request['per_page'])) {
$per_page = sanitize_text_field($request['per_page']);
if(!is_numeric($per_page)){
$per_page = 10;
}
}
$page = ($page - 1) * $per_page;
$table_name = $wpdb->prefix . "wcfm_marketplace_orders";
$sql =
"SELECT * FROM " . $table_name . " WHERE vendor_id = $user_id AND is_trashed != 1";
if (isset($request["status"])) {
$status = sanitize_text_field($request["status"]);
$sql .= " AND order_status = '$status'";
}
if (isset($request["search"])) {
$search = sanitize_text_field($request["search"]);
$sql .= " AND order_id LIKE '$search%'";
}
if (isset($request['name'])) {
$results = [];
$table_name2 = $wpdb->prefix . "users";
$name = sanitize_text_field($request['name']);
$sql2 = "SELECT {$table_name2}.ID";
$sql2 .= " FROM {$table_name2}";
$sql2 .= " WHERE {$table_name2}.display_name LIKE '%$name%'";
$sql2 .= " ORDER BY {$table_name2}.display_name";
$users = $wpdb->get_results($sql2);
if (count($users) > 0) {
$user_str = array();
foreach ($users as $user) {
$user_str[] = $user->ID;
}
$user_strr = implode(',', $user_str);
$sql .= " AND `{$table_name}`.customer_id IN ({$user_strr})";
} else {
return new WP_REST_Response(
[
"status" => "success",
"response" => [],
],
200
);
}
}
$sql .= " GROUP BY $table_name.`order_id` ORDER BY $table_name.`order_id` DESC LIMIT $per_page OFFSET $page";
$items = $wpdb->get_results($sql);
foreach ($items as $item) {
$order = wc_get_order($item->order_id);
//$order1 = wc_get_order($item->order_id);
//$order2 = wc_get_order( $order_id );
//$order_id = $order1->get_id($item);
//$order_data = $order1->get_meta('_barcode_text');
//$final_array = array_values($order_data);
if (is_bool($order)) {
continue;
}
$response = $api->prepare_item_for_response($order, $request);
$order = $response->get_data();
// $order2 = WC_REST_Orders_V1_Controller($order1);
$order3=$order2;
//$my_var = get_post_meta( $order_id, '_wcfmd_delvery_times', true );
//$meta_data = $item->get_formatted_meta_data('_', true);
//$order_data = $order1->get_meta('_wcfmd_delvery_times');
$count = count($order["line_items"]);
$order["product_count"] = $count;
$order["Hello"] = 'zf';
$order["meta_data"]=$order_id;
$line_items = array();
for ($i = 0; $i < $count; $i++) {
$product_id = absint(
$order["line_items"][$i]["product_id"]
);
$product = get_post($product_id);
$product_author = $product->post_author;
if (absint($product_author) != absint($user_id)) {
continue;
}
$commission_data = get_post_meta($product_id, '_wcfmmp_commission', true);
if(!empty($commission_data)){
$order["line_items"][$i]['commission'] = $commission_data;
}
$image = wp_get_attachment_image_src(
get_post_thumbnail_id($product_id)
);
if (!is_null($image[0])) {
$order["line_items"][$i]["featured_image"] = $image[0];
}
$order_item = new WC_Order_Item_Product($order["line_items"][$i]["id"]);
$order["line_items"][$i]["meta"] = $order_item->get_meta_data();
if (is_plugin_active('wc-frontend-manager-delivery/wc-frontend-manager-delivery.php')) {
$table_name = $wpdb->prefix . "wcfm_delivery_orders";
$sql = "SELECT delivery_boy FROM `{$table_name}`";
$sql .= " WHERE 1=1";
$sql .= " AND product_id = '{$product_id}'";
$sql .= " AND order_id = '{$item->order_id}'";
$users = $wpdb->get_results($sql);
if (count($users) > 0) {
$user = get_userdata($users[0]->delivery_boy);
$order["line_items"][$i]['delivery_user'] = [
"id" => $user->ID,
"name" => $user->display_name,
"profile_picture" => $profile_pic,
];
}
}
$line_items[] = $order["line_items"][$i];
}
$order["line_items"] = $line_items;
$results[] = $order;
}
}
This is the current Json data
"status": "success",
"response": [
{
"id": 13828,
"parent_id": 0,
"status": "processing",
"order_key": "",
"number": "13828",
"currency": "EUR",
"version": "5.9.1",
"prices_include_tax": true,
"date_created": "2022-05-05T18:15:44",
"date_modified": "2022-05-05T18:17:06",
"customer_id": 4,
"discount_total": "0.00",
"discount_tax": "0.00",
"shipping_total": "0.00",
"shipping_tax": "0.00",
"cart_tax": "16.67",
"total": "100.00",
"total_tax": "16.67",
"billing": {
"first_name": "i",
"last_name": "m",
"company": "",
"address_1": "107 Rue de Rivoli",
"address_2": "",
"city": "Paris",
"state": "SG",
"postcode": "75001",
"country": "FR",
"email": "",
"phone": ""
},
"shipping": {
"first_name": "i",
"last_name": "m",
"company": "",
"address_1": "107 Rue de Rivoli",
"address_2": "",
"city": "Paris",
"state": "SG",
"postcode": "75001",
"country": "FR",
"phone": ""
},
"payment_method": "",
"payment_method_title": "",
"transaction_id": "",
"customer_ip_address": "",
"customer_user_agent": "",
"created_via": "admin",
"customer_note": "",
"date_completed": null,
"date_paid": "2022-05-05T20:17:06",
"cart_hash": "",
"line_items":
"tax_lines": [
{
"id": 457,
"rate_code": "FR-TVA-1",
"rate_id": 1,
"label": "TVA",
"compound": false,
"tax_total": "16.67",
"shipping_tax_total": "0.00"
}
],
"shipping_lines": [
],
"fee_lines": [
],
"coupon_lines": [
],
"refunds": [
],
"product_count": 1,
"Hello": "zf",
"meta_data": [
null
]
I tried without success such as the commented line but I'am gettting null value or empty at each try.
Thanks you.

Related

Woocommerce update order value after updating cart discount

I want to add maximum discount limit on % discount coupons. I've added this code to do so in cart, but payment gateway is still getting the % discount without the maximum limit set by this code. Will I have to update any other value to fix this?
Payment gateway plugging is getting the total using get_total method.
add_action( 'woocommerce_coupon_options_usage_limit', 'woocommerce_coupon_options_usage_limit', 10, 2 );
function woocommerce_coupon_options_usage_limit( $coupon_id, $coupon )
{
echo '';
// max discount per coupons
$max_discount = get_post_meta( $coupon_id, '_max_discount', true );
woocommerce_wp_text_input( array(
'id' => 'max_discount',
'label' => __( 'Usage max discount', 'woocommerce' ),
'placeholder' => esc_attr( $max_discount, 'woocommerce' ),
'description' => __( 'The maximum discount this coupon can give.', 'woocommerce' ),
'type' => 'number',
'desc_tip' => true,
'class' => 'short',
'custom_attributes' => array(
'step' => 1,
'min' => 0,
),
'value' => $max_discount ? $max_discount : '',
) );
echo '';
}
add_action( 'woocommerce_coupon_options_save', 'woocommerce_coupon_options_save', 10, 2 );
function woocommerce_coupon_options_save( $coupon_id, $coupon ) {
update_post_meta( $coupon_id, '_max_discount', wc_format_decimal( $_POST['max_discount'] ) );
}
// filter to change discount if over max coupon amount
function filter_woocommerce_coupon_get_discount_amount( $discount, $discounting_amount, $cart_item, $single, $instance ) {
$cartCoupons = WC()->cart->get_applied_coupons();
foreach ($cartCoupons as $key => $appliedCoupon) {
$coupon = new WC_Coupon($appliedCoupon);
$couponType = get_post_meta( $coupon->get_id(), 'discount_type', true );
if ($couponType == 'percent') {
$maxCouponAmount = get_post_meta( $coupon->get_id(), '_max_discount', true );
$excludedProducts = explode(",", get_post_meta( $coupon->get_id(), 'exclude_product_ids', true ));
$cartLines = count(WC()->cart->get_cart());
$cartLineItems = WC()->cart->get_cart();
foreach ($cartLineItems as $cartItem){
$cartProductID[] = $cartItem['product_id'];
if (!empty($excludedProducts)) {
$cartLinesWithoutExcluded = array_intersect($cartProductID,$excludedProducts);
} else {
$cartLinesWithoutExcluded = $cartProductID;
}
$cartLinesWithoutExcluded = count($cartLinesWithoutExcluded);
$totalCartItems = $cartLines - $cartLinesWithoutExcluded;
$discount = $maxCouponAmount / $totalCartItems;
}
} else {
$discount = 0.00;
}
return $discount;
}
}
// apply the coupon whether it is max discount or a product price adjustment
function apply_max_amount_or_product_price_adjustment(){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
if ( !is_admin() && !wp_is_json_request() ) {
global $wp, $woocommerce, $post;
$cartCoupons = WC()->cart->get_applied_coupons();
foreach ($cartCoupons as $key => $appliedCoupon) {
$coupon = new WC_Coupon($appliedCoupon);
$maxCouponAmount = get_post_meta( $coupon->get_id(), '_max_discount', true );
$excludedProducts = explode(",", get_post_meta( $coupon->get_id(), 'exclude_product_ids', true ));
$couponType = get_post_meta( $coupon->get_id(), 'discount_type', true );
// $fixedProductPrice = get_post_meta( $coupon->get_id(), '_adjust_price', true );
$couponAmount = WC()->cart->get_coupon_discount_amount( $appliedCoupon );
if (!empty($maxCouponAmount) && $couponType == 'percent' && ($couponAmount >= $maxCouponAmount)) {
$couponAmount = add_filter( 'woocommerce_coupon_get_discount_amount', 'filter_woocommerce_coupon_get_discount_amount', 10, 5 );
}
if ($couponType == 'fixed_cart') {
$cart = WC()->cart->get_cart();
$couponProducts = explode(',',get_post_meta( $coupon->get_id(), 'product_ids', true ));
$fixedPricePerProduct = get_post_meta( $coupon->get_id(), '_price_per_product_amt', true );
foreach( $cart as $cart_item ) {
if (in_array($cart_item['data']->get_parent_id(), $couponProducts)) {
$cart_item['data']->set_price( $fixedPricePerProduct );
}
}
}
}
}
}
add_action('woocommerce_before_calculate_totals', 'apply_max_amount_or_product_price_adjustment', 10, 1);
add_action('woocommerce_coupon_options_usage_limit', 'woocommerce_coupon_options_usage_limit', 10, 2);
function woocommerce_coupon_options_usage_limit($coupon_id, $coupon)
{
echo '';
// max discount per coupons
$max_discount = get_post_meta($coupon_id, '_max_discount', true);
woocommerce_wp_text_input(array(
'id' => 'max_discount',
'label' => __('Usage max discount', 'woocommerce'),
'placeholder' => esc_attr($max_discount, 'woocommerce'),
'description' => __('The maximum discount this coupon can give.', 'woocommerce'),
'type' => 'number',
'desc_tip' => true,
'class' => 'short',
'custom_attributes' => array(
'step' => 1,
'min' => 0,
),
'value' => $max_discount ? $max_discount : '',
));
echo '';
}
add_action('woocommerce_coupon_options_save', 'woocommerce_coupon_options_save', 10, 2);
function woocommerce_coupon_options_save($coupon_id, $coupon)
{
update_post_meta($coupon_id, '_max_discount', wc_format_decimal($_POST['max_discount']));
}
// filter to change discount if over max coupon amount
function filter_woocommerce_coupon_get_discount_amount($discount, $discounting_amount, $cart_item, $single, $instance)
{
$cartCoupons = WC()->cart->get_applied_coupons();
foreach ($cartCoupons as $key => $appliedCoupon) {
$coupon = new WC_Coupon($appliedCoupon);
$couponType = get_post_meta($coupon->get_id(), 'discount_type', true);
if ($couponType == 'percent') {
$maxCouponAmount = get_post_meta($coupon->get_id(), '_max_discount', true);
$excludedProducts = explode(",", get_post_meta($coupon->get_id(), 'exclude_product_ids', true));
$cartLines = count(WC()->cart->get_cart());
$cartLineItems = WC()->cart->get_cart();
foreach ($cartLineItems as $cartItem) {
$cartProductID[] = $cartItem['product_id'];
if (!empty($excludedProducts)) {
$cartLinesWithoutExcluded = array_intersect($cartProductID, $excludedProducts);
} else {
$cartLinesWithoutExcluded = $cartProductID;
}
$cartLinesWithoutExcluded = count($cartLinesWithoutExcluded);
$totalCartItems = $cartLines - $cartLinesWithoutExcluded;
$new_discount = $maxCouponAmount / $totalCartItems;
if ($new_discount < $discount) {
$discount = $new_discount;
}
}
} else {
$discount = 0.00;
}
return $discount;
}
}
// apply the coupon whether it is max discount or a product price adjustment
function apply_max_amount_or_product_price_adjustment()
{
if (is_admin() && !defined('DOING_AJAX'))
return;
if (did_action('woocommerce_before_calculate_totals') >= 2)
return;
if (!is_admin() && !wp_is_json_request()) {
global $wp, $woocommerce, $post;
$cartCoupons = WC()->cart->get_applied_coupons();
foreach ($cartCoupons as $key => $appliedCoupon) {
$coupon = new WC_Coupon($appliedCoupon);
$maxCouponAmount = get_post_meta($coupon->get_id(), '_max_discount', true);
$excludedProducts = explode(",", get_post_meta($coupon->get_id(), 'exclude_product_ids', true));
$couponType = get_post_meta($coupon->get_id(), 'discount_type', true);
// $fixedProductPrice = get_post_meta( $coupon->get_id(), '_adjust_price', true );
$couponAmount = WC()->cart->get_coupon_discount_amount($appliedCoupon);
if (!empty($maxCouponAmount) && $couponType == 'percent' && ($couponAmount >= $maxCouponAmount)) {
$couponAmount = add_filter('woocommerce_coupon_get_discount_amount', 'filter_woocommerce_coupon_get_discount_amount', 10, 5);
}
if ($couponType == 'fixed_cart') {
$cart = WC()->cart->get_cart();
$couponProducts = explode(',', get_post_meta($coupon->get_id(), 'product_ids', true));
$fixedPricePerProduct = get_post_meta($coupon->get_id(), '_price_per_product_amt', true);
foreach ($cart as $cart_item) {
if (in_array($cart_item['data']->get_parent_id(), $couponProducts)) {
$cart_item['data']->set_price($fixedPricePerProduct);
}
}
}
}
}
}
add_action('woocommerce_before_calculate_totals', 'apply_max_amount_or_product_price_adjustment', 10, 1);
add_filter('woocommerce_coupon_get_discount_amount', 'filter_woocommerce_coupon_get_discount_amount', 10, 5);

How to block a country from accessing my website except a few ip addresses?

I would like to block an entire country from accessing my website, except few whitelisted ips. are there any wordpress plugin available?
I have tried Wordfence: https://www.wordfence.com/
but seems it only allows country blocking but not whitelisting certain IP's within the blocked country
<?php
// you can used simple function for block entire country: - India
function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
$output = NULL;
if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
$ip = $_SERVER["REMOTE_ADDR"];
if ($deep_detect) {
if (filter_var(#$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
if (filter_var(#$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
}
$purpose = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
$support = array("country", "countrycode", "state", "region", "city", "location", "address");
$continents = array(
"AF" => "Africa",
"AN" => "Antarctica",
"AS" => "Asia",
"EU" => "Europe",
"OC" => "Australia (Oceania)",
"NA" => "North America",
"SA" => "South America"
);
if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
$ipdat = #json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
if (#strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
switch ($purpose) {
case "location":
$output = array(
"city" => #$ipdat->geoplugin_city,
"state" => #$ipdat->geoplugin_regionName,
"country" => #$ipdat->geoplugin_countryName,
"country_code" => #$ipdat->geoplugin_countryCode,
"continent" => #$continents[strtoupper($ipdat->geoplugin_continentCode)],
"continent_code" => #$ipdat->geoplugin_continentCode
);
break;
case "address":
$address = array($ipdat->geoplugin_countryName);
if (#strlen($ipdat->geoplugin_regionName) >= 1)
$address[] = $ipdat->geoplugin_regionName;
if (#strlen($ipdat->geoplugin_city) >= 1)
$address[] = $ipdat->geoplugin_city;
$output = implode(", ", array_reverse($address));
break;
case "city":
$output = #$ipdat->geoplugin_city;
break;
case "state":
$output = #$ipdat->geoplugin_regionName;
break;
case "region":
$output = #$ipdat->geoplugin_regionName;
break;
case "country":
$output = #$ipdat->geoplugin_countryName;
break;
case "countrycode":
$output = #$ipdat->geoplugin_countryCode;
break;
}
}
}
return $output;
}
if ($_SERVER['HTTP_X_FORWARDED_FOR']){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else{
$ip = $_SERVER['REMOTE_ADDR'];
}
if ($_SERVER['HTTP_X_FORWARDED_FOR']){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else{
$ip = $_SERVER['REMOTE_ADDR'];
}
if(ip_info($ip, "Country")=='India'){ // if you want to any country set like India , Iran , Pakistan etc.
?>
<div class="content">
<p>This website block in INDIA country.</p>
</div>
<?php
die();
}
?>
// you can used simple function for block entire country: - India
function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
$output = NULL;
if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
$ip = $_SERVER["REMOTE_ADDR"];
if ($deep_detect) {
if (filter_var(#$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
if (filter_var(#$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
$ip = $_SERVER['HTTP_CLIENT_IP'];
}
}
$purpose = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
$support = array("country", "countrycode", "state", "region", "city", "location", "address");
$continents = array(
"AF" => "Africa",
"AN" => "Antarctica",
"AS" => "Asia",
"EU" => "Europe",
"OC" => "Australia (Oceania)",
"NA" => "North America",
"SA" => "South America"
);
if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
$ipdat = #json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
if (#strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
switch ($purpose) {
case "location":
$output = array(
"city" => #$ipdat->geoplugin_city,
"state" => #$ipdat->geoplugin_regionName,
"country" => #$ipdat->geoplugin_countryName,
"country_code" => #$ipdat->geoplugin_countryCode,
"continent" => #$continents[strtoupper($ipdat->geoplugin_continentCode)],
"continent_code" => #$ipdat->geoplugin_continentCode
);
break;
case "address":
$address = array($ipdat->geoplugin_countryName);
if (#strlen($ipdat->geoplugin_regionName) >= 1)
$address[] = $ipdat->geoplugin_regionName;
if (#strlen($ipdat->geoplugin_city) >= 1)
$address[] = $ipdat->geoplugin_city;
$output = implode(", ", array_reverse($address));
break;
case "city":
$output = #$ipdat->geoplugin_city;
break;
case "state":
$output = #$ipdat->geoplugin_regionName;
break;
case "region":
$output = #$ipdat->geoplugin_regionName;
break;
case "country":
$output = #$ipdat->geoplugin_countryName;
break;
case "countrycode":
$output = #$ipdat->geoplugin_countryCode;
break;
}
}
}
return $output;
}
if ($_SERVER['HTTP_X_FORWARDED_FOR']){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else{
$ip = $_SERVER['REMOTE_ADDR'];
}
if ($_SERVER['HTTP_X_FORWARDED_FOR']){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
else{
$ip = $_SERVER['REMOTE_ADDR'];
}
if(ip_info($ip, "Country")=='India'){ // if you want to any country set like India , Iran , Pakistan etc.
?>
<div class="content">
<p>This website block in INDIA country.</p>
</div>
<?php
die();
}
?>

Transform JSON structure in cosmos db

I have the following data structure that I'm looking to transform. The structure exist as follows:
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"providers": [
{
"providerNumber": "157833AC",
"providerName": "DR TEST"
}
],
"serviceItems": [
{
"itemName": "INITIAL CONS",
"itemNumber": "100",
"fee": 0,
"isReferenceItem": "true",
"customisations": [
{
"practiceDisplayName": "First Assessment",
"fee": 50,
"isPracticeReferenceItem": "true"
}
]
},
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true",
"customisations": [
{
"practiceDisplayName": "Consult One",
"fee": 23.35,
"isPracticeReferenceItem": "true"
},
{
"practiceDisplayName": "Consult Two",
"fee": 15,
"isPracticeReferenceItem": "false"
}
]
}
]
}
]
}
I'm wanting a query that returns the id, practiceId and extrasCoverservices (serviceTypeName, serviceTypeCode and the serviceItems). I don't want to include the provider information.
I've tried this, but I need to specify the position of the element in the array which I don't want to do. Any help would be much appreciated.
SELECT a.id
, a.practiceId
, [{"serviceTypeName": a.extrasCoverServices[0].serviceTypeName, "serviceTypeCode": a.extrasCoverServices[0].serviceTypeCode, "serviceItems": a.extrasCoverServices[0].serviceItems}]
Update
function sample(documentId) {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT ARRAY_CONCAT([{"itemId": s.itemId, "itemName": s.itemName,"itemNumber":s.itemNumber,"fee":s.fee,"isReferenceItem":s.isReferenceItem}], IS_DEFINED(s.customisations) ? s.customisations : []) as extrasCoverServices FROM a JOIN e in a.extrasCoverServices JOIN s in e.serviceItems WHERE a.id =' + "'" + documentId + "'",
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else {
console.log(feed.length);
var result = feed.flatten(function(x) {
return x.extrasCoverServices;
});
getContext().getResponse().setBody(result);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
You almost had it. To achieve this, you can use features:
inner-document joining using join keyword
explicit JSON composition using { and } wrappers
The first gives you access to the subItem you want to cherry-pick and the second enables you to glue them back together they way you like it.
The query you are looking for should be along the lines of this:
SELECT
a.id,
a.practiceId,
[{
"serviceTypeName": e.serviceTypeName,
"serviceTypeCode" : e.serviceTypeCode,
"serviceItems": e.serviceItems
}] as extrasCoverServices
FROM a
join e in a.extrasCoverServices
Note that you can combine Sql-like select with explicit JSON building in the same query to keep the query more compact. Also, I suggest you use CosmosDB SQL query cheat sheet to easily discover, what's in the toolbox.
function sample(documentId, itemId) {
var collection = getContext().getCollection();
var query = 'SELECT e.serviceTypeCode, '+
' e.serviceTypeName, '+
' s.itemNumber, '+
' ARRAY_CONCAT( '+
' [{ '+
' "itemId": s.itemId, '+
' "itemName": s.itemName, '+
' "fee":s.fee, '+
' "isReferenceItem":s.isReferenceItem '+
' }], '+
' IS_DEFINED(s.customisations) ? s.customisations : []) as extrasCoverServices '+
' FROM a '+
' JOIN e in a.extrasCoverServices '+
' JOIN s in e.serviceItems '+
' WHERE a.id = ' + "'" + documentId + "'";
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
query,
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
var returnResult = [];
for(var i = 0; i<feed.length; i++) {
let serviceItem = feed[i];
let serviceItemsArray = feed[i].extrasCoverServices;
for(var j = 0; j < serviceItemsArray.length; j++) {
let item = serviceItemsArray[j];
let mapped = {
serviceTypeCode: serviceItem.serviceTypeCode
, serviceTypeName: serviceItem.serviceTypeName
, itemId: item.itemId
, itemName: (item.itemName ? item.itemName : item.practiceDisplayName)
, itemNumber: serviceItem.itemNumber
, fee: item.fee
, isReferenceItem: ((item.isReferenceItem && item.isReferenceItem == true) ? item.isReferenceItem: false)
, isPracticeReferenceItem: (item.isPracticeReferenceItem && item.isPracticeReferenceItem == true ? item.isPracticeReferenceItem : false)
};
returnResult.push(mapped);
}
}
if(itemId != undefined) {
var filteredReturnResult = returnResult.filter(r => r.itemId == itemId);
getContext().getResponse().setBody(filteredReturnResult);
return
}
getContext().getResponse().setBody(returnResult);
if (!isAccepted) throw new Error('The query was not accepted by the server.');
})
}
Please use sql like:
SELECT a.id,a.practiceId,e.serviceTypeName,e.serviceTypeCode,e.serviceItems
FROM a
join e in a.extrasCoverServices a
Result:
If you want to make the e.serviceTypeName,e.serviceTypeCode,e.serviceItems into an array, not parallel with id and praticeId, I suggest you using stored procedure in cosmos db.
function sample() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT c.id,c.practiceId,c.extrasCoverServices FROM root c',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else {
var returnResult = [];
for(var i = 0;i<feed.length;i++){
var obj1 = {
id:"",
practiceId:"",
serviceArray :[]
};
obj1.id = feed[i].id;
obj1.practiceId = feed[i].practiceId;
var loopArray = feed[i].extrasCoverServices;
var serviceResult = [];
for(var j = 0;j<loopArray.length;j++){
var obj2 = {
serviceTypeName:"",
serviceTypeCode:"",
serviceItems:[] };
obj2.serviceTypeName=loopArray[j].serviceTypeName;
obj2.serviceTypeCode=loopArray[j].serviceTypeCode;
obj2.serviceItems=loopArray[j].serviceItems;
serviceResult.push(obj2);
}
obj1.serviceArray= serviceResult;
returnResult.push(obj1);
}
getContext().getResponse().setBody(returnResult);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Result:
Hope it helps you.
Update Answer 1:
For your further requirement in your comment, I test a sql for you.
SELECT
a.id,
a.practiceId,
[{
"serviceTypeName": e.serviceTypeName,
"serviceTypeCode" : e.serviceTypeCode,
"serviceItems": [
{"itemName": s.itemName,
"itemNumber":s.itemNumber,
"fee":s.fee,
"isReferenceItem":s.isReferenceItem
},
{"practiceDisplayName":c.practiceDisplayName,
"itemNumber":s.itemNumber,
"fee": c.fee,
"isPracticeReferenceItem":c.isPracticeReferenceItem
}
]
}] as extrasCoverServices
FROM a
join e in a.extrasCoverServices
join s in e.serviceItems
join c in s.customisations
However , the results have multiple items because of the join.
[
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "INITIAL CONS",
"itemNumber": "100",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "First Assessment",
"itemNumber": "100",
"fee": 50,
"isPracticeReferenceItem": "true"
}
]
}
]
},
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "Consult One",
"itemNumber": "200",
"fee": 23.35,
"isPracticeReferenceItem": "true"
}
]
}
]
},
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "Consult Two",
"itemNumber": "200",
"fee": 15,
"isPracticeReferenceItem": "false"
}
]
}
]
}
]
So, I suggest you processing the results in the stored procedure to match your requirement.
function sample() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT a.id, a.practiceId,'+
'[{'+
'"serviceTypeName": e.serviceTypeName, '+
'"serviceTypeCode" : e.serviceTypeCode, '+
'"serviceItems": ['+
'{"itemName": s.itemName,'+
'"itemNumber":s.itemNumber,'+
'"fee":s.fee,'+
'"isReferenceItem":s.isReferenceItem'+
'},'+
'{"practiceDisplayName":c.practiceDisplayName,'+
'"itemNumber":s.itemNumber,'+
'"fee": c.fee,'+
'"isPracticeReferenceItem":c.isPracticeReferenceItem '+
'}'+
']'+
'}] as extrasCoverServices'+
' FROM a '+
' join e in a.extrasCoverServices'+
' join s in e.serviceItems'+
' join c in s.customisations',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else {
var returnResult = [];
var obj1 = {
id:"",
practiceId:"",
extrasCoverServices :[]
};
var temp = "";
for(var i = 0;i<feed.length;i++){
if(temp==feed[i].id){
var extrasArray = obj1.extrasCoverServices[0].serviceItems;
var serviceArray = feed[i].extrasCoverServices[0].serviceItems;
for(var j = 0;j<serviceArray.length;j++){
extrasArray.push(serviceArray[j]);
}
obj1.extrasCoverServices[0].serviceItems = extrasArray;
} else{
obj1.id = feed[i].id;
obj1.practiceId = feed[i].practiceId;
obj1.extrasCoverServices = feed[i].extrasCoverServices;
temp = feed[i].id;
}
}
returnResult.push(obj1);
getContext().getResponse().setBody(returnResult);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Process Result:
[
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "INITIAL CONS",
"itemNumber": "100",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "First Assessment",
"itemNumber": "100",
"fee": 50,
"isPracticeReferenceItem": "true"
},
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "Consult One",
"itemNumber": "200",
"fee": 23.35,
"isPracticeReferenceItem": "true"
},
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true"
},
{
"practiceDisplayName": "Consult Two",
"itemNumber": "200",
"fee": 15,
"isPracticeReferenceItem": "false"
}
]
}
]
}
]
Update Answer 2:
Well,I still focus on implementing your needs through the Stored Procedure.
I add one item without customisations array into serviceItems as below:
[
{
"id": "13fd6574-dc33-4b8c-a09b-a937869d184f",
"practiceId": 2,
"extrasCoverServices": [
{
"serviceTypeName": "OCCUPATIONAL THERAPY",
"serviceTypeCode": "H",
"serviceItems": [
{
"itemName": "INITIAL CONS",
"itemNumber": "100",
"fee": 0,
"isReferenceItem": "true",
"customisations": [
{
"practiceDisplayName": "First Assessment",
"fee": 50,
"isPracticeReferenceItem": "true"
}
]
},
{
"itemName": "CONS TREAT",
"itemNumber": "200",
"fee": 0,
"isReferenceItem": "true",
"customisations": [
{
"practiceDisplayName": "Consult One",
"fee": 23.35,
"isPracticeReferenceItem": "true"
},
{
"practiceDisplayName": "Consult Two",
"fee": 15,
"isPracticeReferenceItem": "false"
}
]
},
{
"itemName": "FOR TEST",
"itemNumber": "333",
"fee": 20,
"isReferenceItem": "true"
}
]
}
]
}
]
SP CODE:
function sample() {
var collection = getContext().getCollection();
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
'SELECT a.id, a.practiceId,'+
'[{'+
'"serviceTypeName": e.serviceTypeName, '+
'"serviceTypeCode" : e.serviceTypeCode, '+
'"serviceItems": e.serviceItems'+
'}] as extrasCoverServices'+
' FROM a '+
' join e in a.extrasCoverServices',
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
else {
for(var i = 0;i<feed.length;i++){
var extraArray = feed[i].extrasCoverServices;
for(var j = 0;j<extraArray.length;j++){
var serviceArray = extraArray[j].serviceItems;
var array = [];
for(var k = 0;k<serviceArray.length;k++){
var o1 = {
"itemName": "",
"itemNumber":"",
"fee" : "",
"isReferenceItem":""
};
console.log(k+"----");
o1.itemName = serviceArray[k].itemName;
o1.itemNumber = serviceArray[k].itemNumber;
o1.fee = serviceArray[k].fee;
o1.isReferenceItem = serviceArray[k].isReferenceItem;
console.log(o1.itemName);
array.push(o1);
if(null != serviceArray[k].customisations){
var customisationsArray = serviceArray[k].customisations;
for(var p = 0;p<customisationsArray.length;p++){
var o2 = {
"practiceDisplayName": "",
"itemNumber":"",
"fee" : "",
"isPracticeReferenceItem":""
};
o2.practiceDisplayName = customisationsArray[p].practiceDisplayName;
o2.itemNumber = o1.itemNumber;
o2.fee = customisationsArray[p].fee;
o2.isPracticeReferenceItem = customisationsArray[p].isPracticeReferenceItem;
array.push(o2);
}
}
}
feed[i].extrasCoverServices[j].serviceItems = array;
}
}
getContext().getResponse().setBody(feed);
}
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Just for summary, I tidied up your last SP code. This is a good thread.
function sample(documentId, itemId) {
var collection = getContext().getCollection();
var query = 'SELECT e.serviceTypeCode, '+
' e.serviceTypeName, '+
' s.itemNumber, '+
' ARRAY_CONCAT( '+
' [{ '+
' "itemId": s.itemId, '+
' "itemName": s.itemName, '+
' "fee":s.fee, '+
' "isReferenceItem":s.isReferenceItem '+
' }], '+
' IS_DEFINED(s.customisations) ? s.customisations : []) as extrasCoverServices '+
' FROM a '+
' JOIN e in a.extrasCoverServices '+
' JOIN s in e.serviceItems '+
' WHERE a.id = ' + "'" + documentId + "'";
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
query,
function (err, feed, options) {
if (err) throw err;
if (!feed || !feed.length) getContext().getResponse().setBody('no docs found');
var returnResult = [];
for(var i = 0; i<feed.length; i++) {
let serviceItem = feed[i];
let serviceItemsArray = feed[i].extrasCoverServices;
for(var j = 0; j < serviceItemsArray.length; j++) {
let item = serviceItemsArray[j];
let mapped = {
serviceTypeCode: serviceItem.serviceTypeCode
, serviceTypeName: serviceItem.serviceTypeName
, itemId: item.itemId
, itemName: (item.itemName ? item.itemName : item.practiceDisplayName)
, itemNumber: serviceItem.itemNumber
, fee: item.fee
, isReferenceItem: ((item.isReferenceItem && item.isReferenceItem == true) ? item.isReferenceItem: false)
, isPracticeReferenceItem: (item.isPracticeReferenceItem && item.isPracticeReferenceItem == true ? item.isPracticeReferenceItem : false)
};
returnResult.push(mapped);
}
}
if(itemId != undefined) {
var filteredReturnResult = returnResult.filter(r => r.itemId == itemId);
getContext().getResponse().setBody(filteredReturnResult);
return
}
getContext().getResponse().setBody(returnResult);
if (!isAccepted) throw new Error('The query was not accepted by the server.');
})
}

Drupal Upgrade:: Need to rewrite pagerquery to version 7

I need to rewrite pagerquery, i have tried out several options adding tags, extend(PagerDefault) but nothing worked for me:
Please help.
My version 6 code is:
$sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '.$sort_join.' WHERE n.uid = %d AND n.type = "case" AND n.status = 1 ORDER BY '. $order;
$sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n WHERE n.uid = %d AND n.type = "case" AND n.status = 1';
$args = array('uid' => $user->uid);
$sql = db_rewrite_sql($sql);
$sql_count = db_rewrite_sql($sql_count);
if ($pager) {
$result = pager_query($sql, variable_get('default_nodes_main', 10), 0, $sql_count, $args);
dsm($result);
}
else {
$result = db_query_range($sql, $args, 0, variable_get('feed_default_items', 10));
}
$num_rows = FALSE;
while ($node = db_fetch_object($result)) {
$output .= node_view(node_load($node->nid), 1);
$num_rows = TRUE;
}
Without knowing the name of your join table this isn't complete, but should get you started:
$query = db_select('node', 'n')
->fields('n', array('nid', 'sticky', 'title', 'created'))
->condition('n.uid', $user->uid)
->condition('n.type', 'case')
->condition('n.status', 1)
->extend('PagerDefault')
->limit(variable_get('default_nodes_main', 10))
->addTag('node_access')
->orderBy('col_name');
$query->join('table_to_join', 'table_alias', 'table_alias.nid = n.nid');
foreach ($query->execute() as $row) {
// Do what you need to
}
if ($vidw == 'my_cases' or $vidw == 'my') { // including private
switch ($sort_by) {
case 'rated':
$order = 'n.sticky DESC, vc.value DESC';
$sort_join = 'LEFT OUTER JOIN {votingapi_cache} vc ON n.nid = vc.content_id AND vc.content_type = "node" AND vc.function = "average"';
break;
case 'discussed':
$order = 'n.sticky DESC, nc.comment_count DESC';
$sort_join = 'LEFT OUTER JOIN {node_comment_statistics} nc ON n.nid = nc.nid';
break;
case 'viewed':
$order = 'n.sticky DESC, nc.totalcount DESC';
$sort_join = 'LEFT OUTER JOIN {node_counter} nc ON n.nid = nc.nid';
break;
case 'recent':
default:
$order = 'n.sticky DESC, n.created DESC';
$sort_join = '';
break;
}
// from taxonomy_select_nodes
$sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '.$sort_join.' WHERE n.uid = %d AND n.type = "case" AND n.status = 1 ORDER BY '. $order;
$sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n WHERE n.uid = %d AND n.type = "case" AND n.status = 1';
$args = array('uid' => $user->uid);
$sql = db_rewrite_sql($sql);
$sql_count = db_rewrite_sql($sql_count);
if ($pager) {
$result = pager_query($sql, variable_get('default_nodes_main', 10), 0, $sql_count, $args);
}
else {
$result = db_query_range($sql, $args, 0, variable_get('feed_default_items', 10));
}
// $output .= taxonomy_render_nodes($result);
$num_rows = FALSE;
while ($node = db_fetch_object($result)) {
$output .= node_view(node_load($node->nid), 1);
$num_rows = TRUE;dsm($output);
}
if ($num_rows) {
$output .= theme('pager', NULL, variable_get('default_nodes_main', 10), 0);
}
else {
$output .= '<p>'. t('There are currently no visible cases in this category.') .'</p>';
}
}
In above drupal 6 code, i have updated the query which gives me result but node_view() and theme() does not work.

simple html dom - cannot redeclair str_get_html()

Im trying to make a class to help with SEO and also compare google API with actual results
class:
<?php
class true_seo {
public $string, $amount;
private $arr;
public function __construct(){}
public function set_g_key( $key ) {
$this->g_key = $key;
}
public function set_phrase( $string ){
if( is_string ( $string ) ) {
$string = array( $string );
}
if( is_array ( $string ) ) {
$this->phrases = $string;
}else{
Throw new exception("incorect input for phrase, string or array");
}
}
public function get_sites_use_spider( $amount ) {
require "simple_html_dom.php";
$main_result = array();
foreach( $this->phrases as $phrase ) {
$APIparams = array("key" => $this->g_key, "q" => $phrase, "start" => 0, "maxResults" => $amount, "filter" => true, "restrict" => "", "safeSearch" => false, "lr" => "lang_en", "ie" => "", "oe" => "");
$data = true_seo::google_search_api( $APIparams, 'http://www.google.co.uk/search', false );
new simple_html_dom();
$html = str_get_html( $data );
$result = array();
foreach( $html->find('li.g h3 a') as $g ) {
$data = $g->parent()->nextSibling();
$other = $data->find('span a');
$x = 0;
foreach( $other as $d ) {
( $x == 0 ? $cache = $d->href : $simular = $d->href );
$x++;
}
$excess_span = $data->find('span',0)->outertext;
if( isset( $data->find('div',0)->tag ) ) {
$excess_div = $data->find('div',0)->outertext;
$title = str_replace( array( $excess_span, $excess_div, '<em>', '</em>', '<br>', '<b>', '</b>' ), array( '','','','','','','' ), $data->outertext );
}else{
$title = str_replace( array( $excess_span, '<em>', '</em>', '<br>', '<b>', '</b>' ), array( '','','','','','' ), $data->outertext );
}
$result[] = array( 'link' => $g->href, 'title' => strip_tags( $title ), 'cache' => $cache, 'simular' => 'http://www.google.co.uk' . $simular );
}
$main_result[$phrase] = $result;
$html->clear();
}
$this->non_api_data = $main_result;
}
public function get_sites_use_api( $amount ) {
$arr = array();
foreach( $this->phrases as $phrase ) {
if( $amount > 4 ) {
$times = $amount / 4;
}else{
$times = 1;
}
$arg = array();
for($x = 0; $x < $times; $x++ ) {
$APIparams = array("key" => $this->g_key, "q" => $phrase, "start" => ($x * 4), "maxResults" => 4, "filter" => true, "restrict" => "", "safeSearch" => false, "lr" => "lang_en", "ie" => "", "oe" => "");
if( $data = true_seo::google_search_api( $APIparams, 'http://ajax.googleapis.com/ajax/services/search/web' ) ) {
$arg = array_merge($arg, $data->responseData->results);
}else{
Throw new exception("Request error: no results returned from Google.");
}
}
$arg = array_reverse( $arg );
$remove = $amount % 4;
if( $amount < 4 ) {
$remove = 4 - $amount;
}
for( $x=0; $x < $remove; $x++ ) {
unset( $arg[$x] );
}
$arg = array_reverse( $arg );
foreach( $arg as $g ) {
$result = array( 'link' => $g->url, 'title' => strip_tags( $g->content ), 'cache' => $g->cacheUrl, 'simular' => 'na' );
$arr[$phrase][] = $result;
}
}
$this->api_data = $arr;
}
public function google_search_api($args, $url, $api = true){
if ( !array_key_exists('v', $args) ) {
$args['v'] = '1.0';
}
$url .= '?'.http_build_query($args, '', '&');
if( $result = #file_get_contents($url) ) {
if( $api == true ) {
return json_decode($result);
}else{
return $result;
}
}else{
Throw new exception("No data returned from url: $url");
}
}
public function set_get_actual( $string ) {
$this->actual->name = $string;
$this->actual->data = file_get_contents( $string );
}
public function get_actual_description(){
require_once "simple_html_dom.php";
new simple_html_dom();
$html = str_get_html( $this->actual->data );
return $html->find('head meta[name=description]',0)->content;
$html->clear();
}
}
?>
called by :
<?php
try{
require "./classes/class_true_seo.php";
$seo = new true_seo();
$seo->set_g_key('ABQIAAAAsWzmZ4RXdIk0a-LqpqKCBRSl_WmKnmsXGmN0kkjN2wkrfEOY-hT2sL-_x5v4NtT3DgElKNsR7FDJDQ');
$seo->set_phrase(array("web design mansfield"));
$seo->get_sites_use_api(10);
ob_start();
foreach( $seo->api_data as $key => $phrase_return ){
echo "<h2>" . $key . "</h2>";
foreach( $phrase_return as $rank => $results ){
$seo->set_get_actual( $results['link'] );
echo "<p class=\"link-head\"><strong>#" . ( $rank + 1 ) . "</strong> " . $results['link'] . "</p>";
echo "<p>" . $results['title'] . "</p>";
#echo "<p>" . $seo->get_actual_title() . "</p>";
echo "<p>" . $seo->get_actual_description() . "</p>";
#echo "<p>" . $seo->get_actual_amount_of('p') . "</p>";
#echo "<p>" . $seo->get_actual_amount_of('h2') . "</p>";
}
}
$api_return = ob_get_clean();
ob_start();
$seo->get_sites_use_spider(10);
foreach( $seo->non_api_data as $key => $phrase_return ){
echo "<h2>" . $key . "</h2>";
foreach( $phrase_return as $rank => $results ){
echo "<p class=\"link-head\"><strong>#" . ( $rank + 1 ) . "</strong> " . $results['link'] . "</p>";
echo "<p>" . $results['title'] . "</p>";
}
}
$non_api_return = ob_get_clean();
}catch(Exception $err){
$error = $err->getMessage();
}
?>
My problem being that I keep getting the error:
Fatal error: Cannot redeclare file_get_html() (previously declared in C:\wamp\www\seo\classes\simple_html_dom.php:37) in C:\wamp\www\seo\classes\simple_html_dom.php on line 41
which is due to the last function in the class get_actual_description().
Can anyone see where im cocking up?
regards,
Phil
put require_once "simple_html_dom.php" outside of function

Resources