Retrieving array of Controllers/Actions - yii2

Is it possible in Yii2 to retrieve an array containing all controllers and actions for the whole application?

I finally ended up with:
protected function actionGetcontrollersandactions()
{
$controllerlist = [];
if ($handle = opendir('../controllers')) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && substr($file, strrpos($file, '.') - 10) == 'Controller.php') {
$controllerlist[] = $file;
}
}
closedir($handle);
}
asort($controllerlist);
$fulllist = [];
foreach ($controllerlist as $controller):
$handle = fopen('../controllers/' . $controller, "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (preg_match('/public function action(.*?)\(/', $line, $display)):
if (strlen($display[1]) > 2):
$fulllist[substr($controller, 0, -4)][] = strtolower($display[1]);
endif;
endif;
}
}
fclose($handle);
endforeach;
return $fulllist;
}

I started with the answer from Andreas Hinderberger, and just fine tuned it. I ended up with something like this:
It uses FileHelper to get all the files recursively, which is useful if you are extending controllers from base classes. It also formats the controller-id/action-id using Inflector::camel2id so they will match your routes.
public function getAllControllerActions()
{
$controllers = \yii\helpers\FileHelper::findFiles(Yii::getAlias('#app/controllers'), ['recursive' => true]);
$actions = [];
foreach ($controllers as $controller) {
$contents = file_get_contents($controller);
$controllerId = Inflector::camel2id(substr(basename($controller), 0, -14));
preg_match_all('/public function action(\w+?)\(/', $contents, $result);
foreach ($result[1] as $action) {
$actionId = Inflector::camel2id($action);
$route = $controllerId . '/' . $actionId;
$actions[$route] = $route;
}
}
asort($actions);
return $actions;
}

As far as I know Yii 2 doesn't have any built-in methods to achieve this. You can only get the current controller and its action.
What's the purpose of it? If you really need this you can write such functionality by yourself.
To get all controllers you should search for a files ending with Conroller. And they can be located in different places of application. For example in nested folders, modules, nested modules, etc. So there is more than just one place for search.
To get all actions you should search for all methods prefixed with action in each controller.
Also don't forget about attached actions in controller actions() method. In framework they are usually ending with Action, take a look for example at rest actions. But no one forces you to name it like that, so there is possibility that some external actions can just have different naming convention (for example if you working in team and don't follow this convention).
And you probably need to exclude such folders as vendor.
So it's not trivial task, but possible with some inaccuracies. I just don't get it what's the point of that.

Follow example walk trought all modules and collect all modules controller actions (no tested):
<?php
$controllerDirs = [];
$controllerDirs[] = \Yii::getAlias('#app/controllers');
if ($commonControllerDir = \Yii::getAlias('#common/controllers', false)) {
$controllerDirs['common'] = $commonControllerDir;
}
foreach (\Yii::$app->modules as $moduleId => $module) {
/*
* get module base path
*/
if (method_exists($module, 'getBasePath')) {
$basePath = $module->getBasePath();
} else {
$reflector = new \ReflectionClass($module['class']);
$basePath = StringHelper::dirname($reflector->getFileName());
}
$basePath .= '/controllers';
$controllerDirs[$moduleId] = $basePath;
}
$actions = [];
foreach ($controllerDirs as $moduleId => $cDir) {
$actions[$moduleId][$cDir] = actionGetcontrollersandactions($cDir);
}
print_r($actions);
function actionGetcontrollersandactions($controllerDir) {
$controllerlist = [];
if ($handle = opendir($controllerDir)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != ".." && substr($file, strrpos($file, '.') - 10) == 'Controller.php') {
$controllerlist[] = $file;
}
}
closedir($handle);
}
asort($controllerlist);
$fulllist = [];
foreach ($controllerlist as $controller):
$handle = fopen($controllerDir . '/' . $controller, "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
if (preg_match('/public function action(.*?)\(/', $line, $display)):
if (strlen($display[1]) > 2):
$fulllist[substr($controller, 0, -4)][] = strtolower($display[1]);
endif;
endif;
}
}
fclose($handle);
endforeach;
return $fulllist;
}

Related

convert csv file to json object with Laravel

I am doing a project with Laravel 7. I have to read a csv file and through a controller passing the data in json format to a view.
Unfortunately I don't know how to do that.
These are my controller methods:
public function index($source)
{
$source = strtolower($source);
switch ($source) {
case "csv":
$file_csv = base_path('transactions.csv');
$transactions = $this->csvToJson($file_csv);
dd(gettype($transactions));
return view('transactions', ['source' => $source, 'transactions' => $transactions]);
break;
case "db":
$transactions = Transaction::all();
dd(gettype($transactions));
return view('transactions', ['source' => $source, 'transactions' => $transactions]);
break;
default:
abort(400, 'Bad sintax error.');
}
}
function csvToJson($filename = '', $delimiter = ',')
{
if (!file_exists($filename) || !is_readable($filename)) {
return false;
}
$header = null;
$data = array();
if (($handle = fopen($filename, 'r')) !== false)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== false)
{
if (!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
As you can see, under the two cases I put a dd with a gettype function inside. In the first case I receive uncorrectly the response array, in the second one I receive correctly the response object.
The converted csv file should have this format:
[{"id":1,"code":"T_218_ljydmgebx","amount":"8617.19","user_id":375,"created_at":"2020-01-19T16:08:59.000000Z","updated_at":"2020-01-19T16:08:59.000000Z"},
{"id":2,"code":"T_335_wmhrbjxld","amount":"6502.72","user_id":1847,"created_at":"2020-01-19T16:08:59.000000Z","updated_at":"2020-01-19T16:08:59.000000Z"}]
Do you know how to convert the array transactions into a json object in the first case?
I don't know if there is any build-in solution on Laravel, but it can be done by PHP.
I didn't test my code. So it might not work, or contain some typos, but I'm sure it will give you some directions.
$cols = ["id","code","amount","user_id","created_at","updated_at"];
$csv = file('folder/name.csv');
$output = [];
foreach ($csv as $line_index => $line) {
if ($line_index > 0) { // I assume the the first line contains the column names.
$newLine = [];
$values = explode(',', $line);
foreach ($values as $col_index => $value) {
$newLine[$cols[$col_index]] = $value;
}
$output[] = $newLine;
}
}
$json_output = json_encode($output);
You can just do this :
$csv= file_get_contents($file);
$array = array_map('str_getcsv', explode(PHP_EOL, $csv));
$json json_encode($array);
If you want to return json object
return $json;
If you want to create a .json file
// Pure PHP
$file = fopen('results.json', 'w');
fwrite($file, $json);
fclose($file);
// Laravel using Storage
Storage::disk('local')->put('public/result.json', $json);
I hope this helps somone.
I have an email marketing application where I made bulk importers. So here is their CSV TO JSON code.
function convert_csv_to_json($csv_data){
// CSV to JSON process 1
$context = array(
'http'=>array(
'follow_location' => false,
'max_redirects' => 1000000
)
);
$context = stream_context_create($context);
if (($handle = fopen($csv_data, "r", false, $context)) !== FALSE) {
$csvs = [];
while(! feof($handle)) {
$csvs[] = fgetcsv($handle);
}
$datas = [];
$column_names = [];
foreach ($csvs[0] as $single_csv) {
$column_names[] = $single_csv;
}
foreach ($csvs as $key => $csv) {
if ($key === 0) {
continue;
}
foreach ($column_names as $column_key => $column_name) {
$datas[$key-1][$column_name] = $csv[$column_key];
}
}
return $json = json_encode($datas);
}
// OR
// CSV to JSON process 1
$cols = ['id',
'owner_id',
'name',
'email',
'country_code',
'phone',
'favourites',
'blocked',
'trashed',
'is_subscribed',
'deleted_at',
'created_at',
'updated_at.'];
$csv = file($csv_data);
$output = [];
foreach ($csv as $line_index => $line) {
if ($line_index > 0) { // I assume the the first line contains the column names.
$newLine = [];
$values = explode(',', $line);
foreach ($values as $col_index => $value) {
$newLine[$cols[$col_index]] = $value;
}
$output[] = $newLine;
}
}
return $json_output = json_encode($output);
}

Laravel modify collection value with another value of another collection

I have a json file like this,
{
"unique_id_001":{
"price_1":264000,
"price_2":2178000,
"price_3":3168000,
"price_6":1089000,
"price_7":3168000
},
"unique_id_002":{
"price_1":264000,
"price_2":2178000,
"price_3":3168000,
"price_6":1089000,
"price_7":3168000
},
"unique_id_003":{
"price_1":264000,
"price_2":2178000,
"price_3":3168000,
"price_6":1089000,
"price_7":3168000
}
}
I convert it to collection and want to set those price_x to another collection.
public static function getOldPrices()
{
$storagePath = storage_path(self::PATH);
$file = File::get($storagePath);
$data = json_decode($file, true);
$collection = \App\Price::hydrate($data);
$oldPrices = $collection->flatten();
return $oldPrices;
}
public static function all()
{
$prices = \App\Price::all();
$old_prices = self::getOldPrices();
foreach ($prices as $price) {
foreach ($old_prices as $old_price) { // is there another way so I can remove this loop?
if ($price->id === $old_price->id) {
$price->price_1 = $old_price->price_1;
$price->price_2 = $old_price->price_2;
$price->price_3 = $old_price->price_3;
$price->price_6 = $old_price->price_6;
$price->price_7 = $old_price->price_7;
}
}
}
return $prices;
}
This code is working and could change the value of each price in $prices. But I wonder if there is other ways, because I used two foreach loop in this code, and I think it is not good.
I got another way using map()
Here is my updated code
$prices = $prices->map(function ($price) use ($oldPrices) {
if ($oldPrice = $oldPrices->firstWhere('id', $price->id)) {
$price->price_1 = $oldPrice->price_1;
$price->price_2 = $oldPrice->price_2;
$price->price_3 = $oldPrice->price_3;
$price->price_6 = $oldPrice->price_6;
$price->price_7 = $oldPrice->price_7;
}
return $price;
});

Sanitizing untrusted HTML5

I want to be able to accept HTML from untrusted users and sanitize it so that I can safely include it in pages on my website. By this I mean that markup should not be stripped or escaped, but should be passed through essentially unchanged unless it contains dangerous tags such as <script> or <iframe>, dangerous attributes such as onload, or dangerous CSS properties such as background URLs. (Apparently some older IEs will execute javascript URLs in CSS?)
Serving the content from a different domain, enclosed in an iframe, is not a good option because there is no way to tell in advance how tall the iframe has to be so it will always look ugly for some pages.
I looked into HTML Purifier, but it looks like it doesn't support HTML5 yet. I also looked into Google Caja, but I'm looking for a solution that doesn't use scripts.
Does anyone know of a library that will accomplish this? PHP is preferred, but beggars can't be choosers.
The black listing approach puts you under upgrade pressure. So each time browsers start to support new standards you MUST draw your sanitizing tool to the same level. Such changes happen more often than you think.
White listing (which is achieved by strip_tags with well defined exceptions) of cause shrinks options for your users, but puts you on the save site.
On my own sites I have the policy to apply the black listing on pages for very trusted users (such as admins) and the whitelisting on all other pages. That sets me into the position to not put much effort into the black listing. With more mature role & permission concepts you can even fine grain your black lists and white lists.
UPDATE:
I guess you look for this:
Allow user submitted HTML in PHP
with HTMLpurifier, how to add a couple attributes to the default whitelist, e.g. 'onclick'
I got the point that strip_tags whitelists on tag level but does accept everything on attribute level. Interestingly HTMLpurifier seems to do the whitelisting on attribute level. Thanks, was a nice learning here.
You might be able to do something along the lines of:
preg_replace('/<\s*iframe\s+[^>]*>.*<\s*\/\s*iframe\s+[^>]*>/i', '', $html);
preg_replace('/<\s*script\s+[^>]*>.*<\s*\/\s*script\s+[^>]*>/i', '', $html);
preg_replace('/\s+onload\s+=\s+"[^"]+"/i', '', $html);
... but then again: you have RegExes, now you have two problems - this might remove more than wanted and leave more than wanted as well.
But since HTML Purifier is probably the most modern and well suited (and open source) project you should still use that one and maybe make adjustments if you really need them.
You can check out one of the following as well:
kses - de facto standard, found a way into wordpress as well
htmLawed - an further developed kses
PHP Input Filter - can filter tags and attributes
Though you also have to make sure that your own page layout doesn't take a hit in including the results due to not closed tags.
Maybe it's better to go on a different approach?
How about telling them what they can use?
In that case you can use use strip_tags. It will be easier and a lot more controllable this way. Very easy to extend in the future aswell
On Ruby I'm using Nokogiri (php version) to parse HTML content. You can parse user's data and remove unnecessary tags or attributes, and then convert it to text.
phpQuery - another parser.
And in PHP there is a strip_tags function.
Or you can manualy remove all attributes:
$dom = new DOMDocument;
$dom -> loadHTML( $html );
$xpath = new DOMXPath( $dom );
$nodes = $xpath -> query( "//*[#style]" ); // all elements with style attribute
foreach ( $nodes as $node ) {
// remove or do what you want
$node -> removeAttribute( "style" );
}
echo $dom -> saveHTML();
See WdHTMLParser class. I use this class for my forum.
Sample with WdHTMLParser :
This class parse the HTML to an array :
<div>
<span>
<br />
<span>
un bout de texte
</span>
<input type="text" />
</span>
</div>
Array :
Array (
[0] => Array (
[name] => div
[args] => Array ()
[children] => Array (
[0] => Array (
[name] => span
[args] => Array ()
[children] => Array (
[0] => Array (
[name] => br
[args] => Array ()
)
[1] => Array (
[name] => span
[args] => Array ()
[children] => Array (
[0] => un bout de texte
)
)
[2] => Array (
[name] => input
[args] => Array (
[type] => text
)
)
)
)
)
)
)
WdHTMLParser array to HTML
I use this class on my website to convert array to HTML.
voyageWdHTML_allowattr : These attributes will be allowed.
voyageWdHTML_allowtag : These tags will be allowed.
voyageWdHTML_special : Make your own rules. Actually, I add "_blank" to each link. And replace <br> to new line (\n) in pre tag.
fix_javascript : You can to enable/disable this function, but it is useless.
Sample php :
<?php
include "WdHTMLParser.php";
include "parser.php";
list($erreur, $message) = (new Parser())->parseBadHTML("<div>
<span>
<a onclick=\"alert('Hacked ! :'(');\">Check javascript</a>
<script>alert(\"lol\");</script>
</span>
</div>");
if ($erreur) {
die("Error : ".$message);
}
echo $message;
Output :
<div>
<span>
<a target="_blank">Check javascript</a>
<pre>alert("lol");</pre>
</span>
</div>
My Parser class :
<?php
class Parser {
//private function fix_javascript(&$message) { }
private function voyageWdHTML_args($tab_args, $objname) {
$html = "";
foreach ($tab_args as $attr => $valeur) {
if ($valeur !== null && $this->voyageWdHTML_allowattr($attr)) {
$html .= " $attr=\"".htmlentities($valeur)."\"";
}
}
return $html;
}
private function voyageWdHTML_allowattr($attr) {
return in_array($attr, array("align", "face", "size", "href", "title", "target", "src", "color", "style",
"data-class", "data-format"));
}
private function voyageWdHTML_allowtag($name) {
return in_array($name, array("br", "b", "i", "u", "strike", "sub", "sup", "div", "ol", "ul", "li", "font", "span", "code",
"hr", "blockquote", "cite", "a", "img", "p", "pre", "h6", "h5", "h4", "h3", "h2", "h1"));
}
private function voyageWdHTML_special(&$obj) {
if ($obj["name"] == "a") { $obj["args"]["target"] = "_blank"; }
if ($obj["name"] == "pre") {
array_filter($obj["children"], function (&$var) {
if (is_string($var)) { return true; }
if ($var["name"] == "br") { $var = "\n"; return true; }
return false;
});
}
}
private function voyageWdHTML($tableau, $lvl = 0) {
$html = "";
foreach ($tableau as $obj) {
if (is_array($obj)) {
if (!$this->voyageWdHTML_allowtag($obj["name"])) {
$obj["name"] = "pre";
if (!isset($obj["children"])) {
$obj["children"] = array();
}
}
if (isset($obj["children"])) {
$this->voyageWdHTML_special($obj);
$html .= "<{$obj["name"]}{$this->voyageWdHTML_args($obj["args"], $obj["name"])}>{$this->voyageWdHTML($obj["children"], $lvl+1)}</{$obj["name"]}>";
} else {
$html .= "<{$obj["name"]}>";
}
} else {
$html .= $obj;
}
}
return $html;
}
public function parseBadHTML($message) {
$WdHTMLParser = new WdHTMLParser();
$message = str_replace(array("<br>", "<hr>"), array("<br/>", "<hr/>"), $message);
$tableau = $WdHTMLParser->parse($message);
if ($WdHTMLParser->malformed) {
$retour = $WdHTMLParser->error;
} else {
$retour = $this->voyageWdHTML($tableau);
//$this->fix_javascript($retour);// To make sur
}
return array($WdHTMLParser->malformed, $retour);
}
}
WdHTMLParser class
<?php
class WdHTMLParser {
private $encoding;
private $matches;
private $escaped;
private $opened = array();
public $malformed;
public function parse($html, $namespace = NULL, $encoding = 'utf-8') {
$this->malformed = false;
$this->encoding = $encoding;
$html = $this->escapeSpecials($html);
$this->matches = preg_split('#<(/?)' . $namespace . '([^>]*)>#', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
$tree = $this->buildTree();
if ($this->escaped) {
$tree = $this->unescapeSpecials($tree);
}
return $tree;
}
private function escapeSpecials($html) {
$html = preg_replace_callback('#<\!--.+-->#sU', array($this, 'escapeSpecials_callback'), $html);
$html = preg_replace_callback('#<\?.+\?>#sU', array($this, 'escapeSpecials_callback'), $html);
return $html;
}
private function escapeSpecials_callback($m) {
$this->escaped = true;
$text = $m[0];
$text = str_replace(array('<', '>'), array("\x01", "\x02"), $text);
return $text;
}
private function unescapeSpecials($tree) {
return is_array($tree) ? array_map(array($this, 'unescapeSpecials'), $tree) : str_replace(array("\x01", "\x02"), array('<', '>'), $tree);
}
private function buildTree() {
$nodes = array();
$i = 0;
$text = NULL;
while (($value = array_shift($this->matches)) !== NULL) {
switch ($i++ % 3) {
case 0: {
if (trim($value)) {
$nodes[] = $value;
}
}
break;
case 1: {
$closing = ($value == '/');
}
break;
case 2: {
if (substr($value, -1, 1) == '/') {
$nodes[] = $this->parseMarkup(substr($value, 0, -1));
} else if ($closing) {
$open = array_pop($this->opened);
if ($value != $open) {
$this->error($value, $open);
}
return $nodes;
} else {
$node = $this->parseMarkup($value);
$this->opened[] = $node['name'];
$node['children'] = $this->buildTree($this->matches);
$nodes[] = $node;
}
}
}
}
return $nodes;
}
public function parseMarkup($markup) {
preg_match('#^[^\s]+#', $markup, $matches);
$name = $matches[0];
preg_match_all('#\s+([^=]+)\s*=\s*"([^"]+)"#', $markup, $matches, PREG_SET_ORDER);
$args = array();
foreach ($matches as $m) {
$args[$m[1]] = html_entity_decode($m[2], ENT_QUOTES, $this->encoding);
}
return array('name' => $name, 'args' => $args);
}
public function error($markup, $expected) {
$this->malformed = true;
printf('unexpected closing markup "%s", should be "%s"', $markup, $expected);
}
}
To make sur use, you can use this function (mybb.com) :
<?php
class Parser {
private function fix_javascript(&$message) {
$js_array = array(
"#(&\#(0*)106;?|&\#(0*)74;?|&\#x(0*)4a;?|&\#x(0*)6a;?|j)((&\#(0*)97;?|&\#(0*)65;?|a)(&\#(0*)118;?|&\#(0*)86;?|v)(&\#(0*)97;?|&\#(0*)65;?|a)(\s)?(&\#(0*)115;?|&\#(0*)83;?|s)(&\#(0*)99;?|&\#(0*)67;?|c)(&\#(0*)114;?|&\#(0*)82;?|r)(&\#(0*)105;?|&\#(0*)73;?|i)(&\#112;?|&\#(0*)80;?|p)(&\#(0*)116;?|&\#(0*)84;?|t)(&\#(0*)58;?|\:))#i",
"#(o)(nmouseover\s?=)#i",
"#(o)(nmouseout\s?=)#i",
"#(o)(nmousedown\s?=)#i",
"#(o)(nmousemove\s?=)#i",
"#(o)(nmouseup\s?=)#i",
"#(o)(nclick\s?=)#i",
"#(o)(ndblclick\s?=)#i",
"#(o)(nload\s?=)#i",
"#(o)(nsubmit\s?=)#i",
"#(o)(nblur\s?=)#i",
"#(o)(nchange\s?=)#i",
"#(o)(nfocus\s?=)#i",
"#(o)(nselect\s?=)#i",
"#(o)(nunload\s?=)#i",
"#(o)(nkeypress\s?=)#i"
);
$message = preg_replace($js_array, "$1<b></b>$2$4", $message);
}
}
I decided to just use html5lib-python. This is what I came up with:
#!/usr/bin/env python
import sys
from xml.dom.minidom import Node
import html5lib
from html5lib import (HTMLParser, sanitizer, serializer, treebuilders,
treewalkers)
parser = HTMLParser(tokenizer=sanitizer.HTMLSanitizer,
tree=treebuilders.getTreeBuilder("dom"))
serializer = serializer.htmlserializer.HTMLSerializer(omit_optional_tags=False)
document = parser.parse(sys.stdin.read(), encoding="utf-8")
# find the <html> node
for child in document.childNodes:
if child.nodeType == Node.ELEMENT_NODE and child.nodeName == 'html':
htmlNode = child
# find the <body> node
for child in htmlNode.childNodes:
if child.nodeType == Node.ELEMENT_NODE and child.nodeName == 'body':
bodyNode = child
# serialize all children of the <body> node
for child in bodyNode.childNodes:
stream = treewalkers.getTreeWalker("dom")(child)
sys.stdout.write(serializer.render(stream, encoding="utf-8"))
Example input:
<script>alert("hax")</script>
<p onload="alert('this is a dangerous attribute')"><b>hello,</b> world</p>
Example output:
<script>alert("hax")</script>
<p><b>hello,</b> world</p>
I personally use HTML Purifier for this exact purpose:
http://htmlpurifier.org/docs
It works well and allows you to customize down to every tag and attribute. So far I have had no security issues with this plugin.

drupal custom block module: how to display dynamic generated html from hook_block_view(...)?

i would like to output dynamic generated html content instead of the translatable message but i can't make it work:
function custom_logo_module_block_view($delta = '') {
// don't worry about switch($delta) logic
// perform some operations and then display some generated html
// (maybe use the template(...) function)
// works fine but i'd like to print html
$block['content'] = t('No content available.');
return $block;
}
how can i print out generated html into a block?
i can't find any solutions or code examples. i think i might be pointing towards the wrong direction so best practice suggestions are welcome.
function custom_logo_module_block_view($delta = '') {
$block = array();
if ($delta == 'example') {
$block = array(
'subject' => t('Active users list'),
'content' => example_block_content()
);
}
return $block;
}
function example_block_content() {
// Query for active users from database
$users = db_select('users', 'u')
->fields('u', array('uid', 'name'))
->condition('u.status', 1)
->execute()
->fetchAll();
// Prepare items for item list
$items = array();
foreach ($users as $user) {
$items[] = l($user->name, "user/{$user->uid}");
}
$output = t('No active users available.');
if (!empty($items)) {
$output = theme('item_list', array('items' => $items));
}
return $output;
}
Update regarding your comments...
As far as I understand by some result you mean generated data from database. In this case you can try something like this:
function example_block_content() {
// Query for active users from database
$users = db_select('users', 'u')
->fields('u', array('uid', 'name'))
->condition('u.status', 1)
->execute()
->fetchAll();
$output = '';
foreach ($users as $user) {
$output.= '<div>'. $user->name .'</div>';
}
$output = "<div>Hello World". $output ."</div>";
return $output;
}
This will give you the following output:
<div>Hello World
<div>admin</div>
<div>ndrizza</div>
<div>Vlad Stratulat</div>
...
</div>
Or you can try:
function custom_logo_module_block_view($delta = '') {
$block = array();
if ($delta == 'example') {
$block = array(
'subject' => t('Active users list'),
// this will return "Hello World + some result" text inside <div>
'content' => "<div>Hello World + some result</div>"
);
}
return $block;
}
Both of this ways are working but they are not the right ways. The right way to generate content is in my first answer. Read more about theming in Drupal.

json formatting string to number

My Json output generates;
[
{
"a1_id":"7847TK10",
"output2":"7847TK10",
"output4":"something",
"output5":"3stars.gif",
"output9": "269000",
...
etc. etc.
The google visualization api asks for a number format for the output9 element e.g.:
"output9": 269000 instead of "output9": "269000". How can I achieve this for this element?
My json.php generates the json output like this:
?>
{
"total": <?php echo $total ?>,
"success": true,
"rows": [
// Iterate over the rows
$nextRow= $result->nextRow();
$r = 1;
$info = array();
while ( $nextRow ) {
$nextColumn = $result->nextColumn();
// Has this column been printed already
if ( $unique )
{
$d = $result->getDataForField($unique);
if ( array_key_exists($d, $already) )
{
$nextRow= $result->nextRow();
continue;
}
$already[$d] = true;
}
echo '{';
// Iterate over the columns in each row
while ( $nextColumn )
{
// Get the variable
$variable = $result->getOutputVariable();
$name = $variable->getName(true);
$data = $result->getDataForField();
if ( !isset($info[$name]) ) {
$info[$name]['translate'] = $variable->shouldTranslate();
$info[$name]['type'] = $variable->getDataType();
$info[$name]['linkable'] = $variable->isLinkable();
}
// Translate the data if requested
if ( $info[$name]['translate'] ) {
$data = LQMTemplate::_($data);
}
$data = $variable->format($data, false);
$type = $info[$name]['type'];
if ( ($type == 'bool') or ($type == 'boolean') )
{
$data = $data ? '1' : '0';
echo "'$name':$data";
} elseif ( $encode ) {
// Can we use json_encode ?
// str_replace because some versions of PHP have a bug that will over escape forward slashes
echo "\"$name\":".str_replace('\\/', '/', json_encode($data));
} else {
$data = LQMUtility::jsonEscape($data, '"');
//echo "'$name':\"$data\"";
echo "\"$name\":\"$data\"";
}
// Conditionally print the next column
$nextColumn = $result->nextColumn();
if ( $nextColumn ) echo ",\n ";
}
// Conditionally print the next column
$nextRow = $result->nextRow();
echo $nextRow ? "},\n" : "}\n";
$r++;
}
unset($result);
echo ']}';
}
}
This depends on how you are generating your JSON.
For example, if you were using a Ruby backend, you could call:
"output9" => output9.to_i
There are various helper methods in different languages (e.g. Java and Javascript have parseInt() functions) to change a string into an integer.
Edit:
If your JSON is being generated by PHP, cast the string to an integer:
$json['output9'] = int($output9_value);
That should get rid of the quotation marks.