cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

it seems you have indexAction() nested in the _getTranslation() method, fix the brackets and then see if it works.

cereal 1,524 Nearly a Senior Poster Featured Poster

Also:

filter_var($not_an_int, FILTER_VALIDATE_INT);

Returns FALSE when it's not an integer: http://ideone.com/O3wyIS

diafol commented: I favour this one +15
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

you could use filter_var() with FILTER_SANITIZE_NUMBER_INT:

filter_var($not_an_int, FILTER_SANITIZE_NUMBER_INT);
filter_var($actual_int, FILTER_SANITIZE_NUMBER_INT);

Will return string, that can be casted, se an example here:

Docs: http://php.net/manual/en/filter.filters.sanitize.php

cereal 1,524 Nearly a Senior Poster Featured Poster

/// edit
Sorry D, just saw your post! ;D

As you see, from the dump, age is not set in the POST request and there is nothing similar, a part the DOB from which you could calculate the age:

$birth = "{$year}-{$month}-{$day}";
$dob = new DateTime($birth);
$now = new DateTime();
$age = $now->diff($dob)->format('%y');

If you have an input field named age in the form, then make sure it is inside the correct <form> scope.

A part that, md5 is very weak choice to save passwords, use password_hash() and password_verify() to perform the check. See:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

it seems fine. Are you sure $_POST['age'] is set? Check the submit form or do a var_dump($_POST); to see what is really sent with the request, maybe is not age but Age or something similar.

cereal 1,524 Nearly a Senior Poster Featured Poster

To make it available in the scope of the function you must declare it as global:

function test($id){
    global $conn;
    /// then you can use it
}

Docs: http://php.net/manual/en/language.variables.scope.php

cereal 1,524 Nearly a Senior Poster Featured Poster

The argument for function_exists() must be a string, so:

if( ! function_exists(prepare_insert))

should be:

if( ! function_exists('prepare_insert'))

Docs: http://php.net/function-exists
Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

To tell the truth, there is a space between the substitution and the flags:

RewriteRule ^new/([0-9]+)/?$ new.php?msgID=$1 [R=301,L]
           ↑                ↑                ↑
         space            space            space

What you returned is without the space. That rule works fine for me, so could you share the code of the new.php file? Because, I really don't have other suggestions right now.

rproffitt commented: Gimme my spaces. +11
cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, my mistake :) I forgot to prepend the correct flag, it's R=301:

RewriteRule ^new/([0-9]+)$ new.php?msgID=$1 [R=301,L]
RewriteRule ^new/([0-9]+)/$ new.php?msgID=$1 [R=301,L]

where R stands for Redirect:

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok and what is the error in the Apache error.log? It could be a loop, which could mean a missing rewrite condition, like:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

Used to avoid conflicts with existing files and directories. Now can you share the full rewrite rules and the relevant part of the new.php script?

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

the composer command development-enable is part of the zf-development-mode tools which ships in version 3.0 and requires PHP 5.6 or PHP 7.0, you're using 5.4, so it won't be installed. See if you can install version 2.* of these tools, as it should support your PHP version. For more information see:

cereal 1,524 Nearly a Senior Poster Featured Poster

So, if you do:

/new/155/

With an ending slash it matches correctly? If the new.php file is in localhost/ try these:

RewriteRule ^project/new/([0-9]+)$ new.php?msgID=$1 [L,301]
RewriteRule ^project/new/([0-9]+)/$ new.php?msgID=$1 [L,301]

Otherwise, if it's in localhost/project/ and the .htaccess file is in the same path, remove the project token from the rewrite rules. You can test them here:

Consider also to set a RewriteBase to avoid issues with paths, if that is the problem.

cereal 1,524 Nearly a Senior Poster Featured Poster

the thing is that i call the php fuction in a separate file that doesn't get the $_GET id

$_GET is a superglobal variable, so it's available in all the scopes of the script, even if you execute a function into an included script. Try $_GET['msgID'] as defined in the rewrite rule.

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, so the /155 segment should be the msg_id, correct? Can you show us the rewrite rules? Maybe you just need to point to another index, try to dump the $_GET array var_dump($_GET); to see what is set.

If I can suggest, consider to include a router into your application, something like nikic/FastRoute:

This is already in the Slim framework, and allows you to define a new link like this:

$app = new \Slim\App();
$app->get('/messages/{msg_id}/{another_var}', function($request, $response, $args) {
    echo $args['msg_id'] . ' ' . $args['another_var'];
});

Adding variables at that point becomes easy.

cereal 1,524 Nearly a Senior Poster Featured Poster

What are you using to build those links? Mod rewrite or a router? (Slim perhaps?)

If the rewrite rule defines msg_id then it will be accessible through that link, otherwise you have to append it /project/new/155?msg_id=123 or change the rule.

cereal 1,524 Nearly a Senior Poster Featured Poster

The backtick is the operator used to define those objects known as identifiers: table names, columns, databases and to distinguish a column name, for example, from a reserved word. See: http://dev.mysql.com/doc/refman/5.7/en/identifiers.html

To test your query, open the mysql client and run:

\W -- to enable warnings
SELECT `type` FROM `messages` WHERE `msg_id` = 1;

If it runs fine, then see if $_GET['msg_id'] is set, because, otherwise, it's like sending this query:

SELECT `type` FROM `messages` WHERE `msg_id` = ;

Which will raise the same syntax error.

cereal 1,524 Nearly a Senior Poster Featured Poster

Add backticks to type, as suggested by Pritaeas:

SELECT `type` FROM ...
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi!

The method/function fetchAll() of the PDO library returns an array, which is an empty array if no rows are matched, what you want here is probably fetchColumn():

$type = $stmt->fetchColumn();

And you also want to use prepared statements: I know I repeat myself a lot on this subject, but it's really important, your current code is exposed to SQL injection, I could delete your entire database from there. Write it correctly also for the other users that will read this forum and take your code as example. Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

@phpio

Hi,
the source of __FILE__ (and the other files in the same path) can still be read with this line:

include "php://filter/convert.base64-encode/resource=index.php";

This is a variant of the LFI (Local File Inclusion attack) that uses php://filter and will return a base64 string that, converted, shows the source code. When the filesystem was accessible then reading the contents of files, like /etc/passwd, was simply a matter of writing the correct path.

More info about php:// @ http://php.net/manual/en/wrappers.php.php

diafol commented: You are a naughty boy cereal :D +15
cereal 1,524 Nearly a Senior Poster Featured Poster
Update

Dani it seems it was my Chromium browser, I checked the option through Mozilla Firefox and now (48h later) is still kept. I don't undertand the reason, as it should be a simple POST request and I haven't seen such issues on other websites. However, I realized that my system has not upgraded Chromium in the last month, there could be a relation (?)

For now I mark it solved, thank you :)

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

Warning: mysqli_query() expects parameter 1 to be mysqli, null given

means that $connection is NULL, you have to create the connection to the database. See:

cereal 1,524 Nearly a Senior Poster Featured Poster

Simple Advice

This is just a reminder. When setting environment variables through .htaccess, CLI or dotenv use filter_var() to evaluate a boolean. For example, start the built-in PHP server with these variables:

DEBUG=FALSE LOG=TRUE SMS=1 SMTP=0 CONNECT=yes BACKUP=no php -d variables_order=EGPCS -S localhost:8000

And then test through boolval(): if you forget to use 1 and 0, then something can go wrong as the variable is evaluated like a string and will always return TRUE. By using filter_var(), with the appropriate filter to validate boolean, you get more flexibility as it:

returns TRUE for "1", "true", "on" and "yes". Returns FALSE otherwise.

Docs: http://php.net/manual/en/filter.filters.validate.php

cereal 1,524 Nearly a Senior Poster Featured Poster

You're not hitting the refresh button or anything, are you?

No no, Dani.

Look, to test, three hours ago I logged into my old account (_1), there the option was still checked so I watched this thread: as expected, I received a notification on your update. It does not work on cereal, the setting here disappears.

cereal 1,524 Nearly a Senior Poster Featured Poster

No luck Dany, now it is again unchecked :(

cereal 1,524 Nearly a Senior Poster Featured Poster

Well, okay, I was sure about it but not anymore, I updated my profile after your last message and now is still checked, so it seems fine.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hello Dani,

I hate to say that, but it is not solved, same issue ;(

cereal 1,524 Nearly a Senior Poster Featured Poster

Try to increase the timeout. If you're using curl, then increase the values of connect_timeout and timeout, default should be 30 seconds.

cereal 1,524 Nearly a Senior Poster Featured Poster

Is $conn1 a PDO or a MySQLi resource? It connects to the database correctly? Follow the documentation of the chosen library to properly work with prepared statements. If you just want to verify if the DATE() works fine for you, then use the first example.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

if you ever shared the videos on Twitter then check the Archive.org:

Sincerly, I had difficult to find valid data in those copies but I'm probably doing something wrong. Ask to the archivists, maybe they can help you.

cereal 1,524 Nearly a Senior Poster Featured Poster

@phpio

Hi,

test diafol's script and execute / you get the system root, you can traverse the filesystem, you can arrive to the passwd file from there. Also, it's possible to:

  • download the script that executes the code
  • write to the parent directory through the error_log() function
  • execute SQLite and create a database directly in RAM

I suggest you to stop this box, and start from a new installation, set correct permissions otherwise the system can be compromised.

cereal 1,524 Nearly a Senior Poster Featured Poster

@diafol

Actually it is possible and it is also possible to overwrite files or inject code into the RAM... honeypot? :D

cereal 1,524 Nearly a Senior Poster Featured Poster

Example:

$sql = "INSERT INTO `tentb` (`edate`) VALUES(DATE($edate))";

But you should be using prepared statements, so:

$sql = $db->prepare("INSERT INTO `tentb` (`edate`) VALUES(DATE(:edate))");
$sql->execute([':edate' => $edate]);
cereal 1,524 Nearly a Senior Poster Featured Poster

If you like something like OneDrive then you could set up WebDAV, just make sure Apache is running with the mod_dav modul, see:

cereal 1,524 Nearly a Senior Poster Featured Poster

In the insert query you can use the DATE() function, see:

cereal 1,524 Nearly a Senior Poster Featured Poster

It works, thank you as always Dani!

cereal 1,524 Nearly a Senior Poster Featured Poster

Hello,

everytime I set the checkbox to get community related e-mails and update the profile, it seems to work and if it occurs an event I get the notification, but if I close the window and come back the option is again unchecked and I don't get anymore notifications.

Dani, if you recall, I have already written about this to you via PM, couple of weeks ago and, at that time, we thought it was my oversight, but it seems the same issue as, after those tests, it never worked again.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hello,

are you aware that the referrer can be spoofed? Simple test:

  1. open a terminal and type: nc -l 8000
  2. open another terminal and type: curl --verbose --header --referer http://google.com/ http://localhost:8000/

You'll get:

GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: localhost:8000
Accept: */*
Referer: http://google.com/

More information here: https://en.wikipedia.org/wiki/Referer_spoofing

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

you can setup a replication model: master to master or master to slave. See:

I suggest you to do a research on Google about MySQL Replication, you will find a lot of tutorials and solutions.

cereal 1,524 Nearly a Senior Poster Featured Poster

@Antony try:

SELECT * FROM `TABLENAME` ODER BY date_format(str_to_date(`TIME_COLUMN`, '%r'), '%T') ASC;

This will convert the string to a timestamp that MySQL can parse, then use %T to get the order in the 24H format. But, as suggested, it's better to convert the existing rows into the 24H format and then always save in that format, to avoid extra processing. So you could run an update query, just like above:

UPDATE `TABLENAME` SET `TIME_COLUM` = date_format(str_to_date(`TIME_COLUMN`, '%r'), '%T');

Replace TABLENAME and TIME_COLUMN with yours and remember to test on a copy.

Rule is: save always in UTC, save always in the format that the database can parse, then convert for the client.

For more info see:

Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

Addition:

I forgot CI ships with an Output class, which is loaded by default, so you can also send JSON data in this style:

$this->output
     ->set_header('HTTP/1.1 200 OK')
     ->set_content_type('application/json', 'utf-8')
     ->set_output(json_encode($result, JSON_NUMERIC_CHECK));

For more info see: http://www.codeigniter.com/userguide2/libraries/output.html

cereal 1,524 Nearly a Senior Poster Featured Poster

Hello,

in ./application/core/ create the file MY_Controller.php and extend it to CI_Controller and add a public (or protected) $data:

class MY_Controller extends CI_Controller {

    public $data;
    public function __construct()
    {
        parent::__construct();
        $this->data['menu'] = 'MENU DATA HERE';
    }
}

Then extend your controllers to MY_Controller instead of CI_Controller and when you want to send data to the views use $this->data instead of the canonical $data, for example:

class Blog extends MY_Controller {

    public function __construct()
    {
        parent::__construct();
    }

    public function index()
    {
        $this->data['title'] = 'Blog Index';

        $this->load->view('common/header', $this->data);
        $this->load->view('blog/index', $this->data);
        $this->load->view('common/footer', $this->data);
    }
}

And it should work. Due to the nature of CI you don't have a lot of flexibility, if you are still starting consider other solutions like SlimPHP & co.

cereal 1,524 Nearly a Senior Poster Featured Poster

@Mario no problem. The blank page can be caused by a PHP error, check the PHP error log or the log file created by CodeIgniter, it should be in ./application/logs/ and his verbosity can be set through the ./application/config/config.php file, also see if the index.php page has the error_reporting() enabled.

About the view

You are correct but, the view must be set by another method, and you should use the data_fik() method to get only the JSON response. In your view file you have this line:

$.getJSON("<?php echo site_url('/control_factor_gei/data_fik');?>",

which is requesting the JSON data from the data_fik method, so the view cannot generate by the same method (unless you set a query parameter like data_fik?get=source and data_fik?get=json and set some conditional statements to manage those parameters), but if this is not necessary you can write something like this:

public function data_fik()
{
    # query
    # set header
    # print JSON response
}

public function data_view()
{
    # set the view here
}

Then, when you want to access the page, open /control_factor_gei/data_view. Is this more clear now? If you have doubts let us know.

//
@upvoter, thanks for the vote on the duplicate post, made my day lol :D

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

go to http://regexr.com/3eb88 and mousehover the components of the expression (or hit the Explain tab), it will explain the meaning of each block. If you have some sample data you can paste it in their form and see how it is applied.

For example, try to change [\W_] to [\w] to see what is parsed.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

in your method controller data_fik() replace this:

print json_encode($result, JSON_NUMERIC_CHECK);
$data['body'] = 'hchart_elec';
$this->load->view('main', $data);

with:

header('Content-Type: application/json; charset=utf8');
echo json_encode($result, JSON_NUMERIC_CHECK);

You don't neet to load a view, because the method will return JSON content, so just set the correct content type header and print it.

And it should work, you can also test what is received by getJSON() through console.log():

console.log(json);

You can also manually open the data_fik link to see if the headers and the contents are correct, the developer console in Google Chrome or extensions like Postman should help you in the debug process.

Bye.

cereal 1,524 Nearly a Senior Poster Featured Poster

@rproffitt hi, that bit.ly points to http://renardwatches.com/
(it seems to work for me)

cereal 1,524 Nearly a Senior Poster Featured Poster

Hello,

so, standing at the original example you want two rows for each date > item, correct?

Use implode() after each cycle, change this:

# loop each date > item
foreach($items as $item)

    # loop each date > item > item
    foreach($item as $elem)
        $r[] = sprintf('%s %s %s'
                     , $elem->attributes()->Name
                     , $elem->attributes()->Type
                     , $elem);

to:

# loop each date > item
foreach($items as $item)
{
    # initialize the $r array at each loop
    $r = [];

    # loop each date > item > item
    foreach($item as $elem)
    {
        $r[] = sprintf('%s %s %s'
                     , $elem->attributes()->Name
                     , $elem->attributes()->Type
                     , $elem);
    }

    # convert the $r array to a string
    $s[] = implode(',', $r);
}

The contents of $s will look like this:

array (2) [
    string (184) "received Date 2015/12/18 00:00,accepted Date 2016/03/31 00:00,aheadofprint Date 2016/04/14 00:00,entrez Date 2016/04/15 06:00,pubmed Date 2016/04/15 06:00,medline Date 2016/04/15 06:00"
    string (152) "epublish Date 2016/05/23 00:00,entrez Date 2016/07/12 06:00,pubmed Date 2016/07/12 06:00,medline Date 2016/07/12 06:00,pmc-release Date 2017/01/01 00:00"
]

If you want them all in the same string, then just initialize the $r array before or the first loop (# loop each <date> node) and move the implode out of the loops, at the end, basically:

$r = [];

# loops

$s = implode(',', $r);
cereal 1,524 Nearly a Senior Poster Featured Poster

Yes, I noticed that only after your answer. Usually Stefan writes about PHP, so I went in automatic. My bad.

cereal 1,524 Nearly a Senior Poster Featured Poster

Wait, was it about the editor?! O_O
I thought it was about PHP, sorry!

cereal 1,524 Nearly a Senior Poster Featured Poster

If you just need to remove what comes after the first occurrence of the bracket and display what is remaining, then you could basically loop the input into strstr(), like this:

$line = 'Águila (El Salvador)';
$out = strstr($line, '(', TRUE) . '(';
print $out; # Águila (

See: http://php.net/manual/en/function.strstr.php
Example:

<?php

$fp = function($file) {

    $out   = '';
    $lines = file($file);

    foreach($lines as $line)
        $out .= strstr($line, '(', TRUE) . '(' . PHP_EOL;

    return $out;
};

$output = $fp('./input.txt');
print $output;

Or switch to fopen if the input is a big file.

cereal 1,524 Nearly a Senior Poster Featured Poster

It happens because you have to manually move to the next node, you can do like this:

<?php

$file = 'dates.xml';
$xml  = simplexml_load_file($file);

# loop each <date> node
foreach($xml->date as $node) {

    $items = $node->children();

    # loop each date > item
    foreach($items as $item)

        # loop each date > item > item
        foreach($item as $elem)
            $r[] = sprintf('%s %s %s'
                         , $elem->attributes()->Name
                         , $elem->attributes()->Type
                         , $elem);
}

print_r($r);

Will return:

Array
(
    [0] => received Date 2015/12/18 00:00
    [1] => accepted Date 2016/03/31 00:00
    [2] => aheadofprint Date 2016/04/14 00:00
    [3] => entrez Date 2016/04/15 06:00
    [4] => pubmed Date 2016/04/15 06:00
    [5] => medline Date 2016/04/15 06:00
    [6] => epublish Date 2016/05/23 00:00
    [7] => entrez Date 2016/07/12 06:00
    [8] => pubmed Date 2016/07/12 06:00
    [9] => medline Date 2016/07/12 06:00
    [10] => pmc-release Date 2017/01/01 00:00
)

To get the attributes, in this case, since $elem will be a SimpleXMLElement object you can use the attributes() method:

Use var_dump() or a debugger like this to see which kind of object you are iterating, for example:

foreach($items as $item)
    sd($item);

Returns:

SimpleXMLElement (2) (
    public @attributes -> array (2) [
        'Name' => string (7) "History"
        'Type' => string (4) "List"
    ]
    public Item -> array (6) [
        string (16) "2015/12/18 00:00"
        string (16) "2016/03/31 00:00"
        string (16) "2016/04/14 00:00"
        string (16) "2016/04/15 06:00"
        string (16) "2016/04/15 06:00"
        string (16) "2016/04/15 06:00"
    ]
)

So you can see the attributes of the main node: