cereal 1,524 Nearly a Senior Poster Featured Poster

It's not cool to kick trashcans Dani :p I hope you'll get better soon!

cereal 1,524 Nearly a Senior Poster Featured Poster

You're welcome, you could try PHPWord:

Which is a library to generate docx, odt, rtf and pdf files. But I didn't tested yet.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,
if you choose PHP then use variables, for example:

<p>Client Name: <?php echo "$firstname $lastname"; ?></p>

To assign the values to the variables $firstname and $lastname you can use the input submitted by a form:

<form method="post" action="document.php">

    <label for="firstname">Firstname:</label>
    <input type="text" name="firstname" />
    <br />

    <label for="lastname">lastname:</label>
    <input type="text" name="lastname" />
    <br />

    <input type="submit" name="submit" value="submit" />

</form>

And in document.php:

<?php

    $firstname = $_POST['firstname'];
    $lastname  = $_POST['lastname'];

?>

<p>Client Name: <?php echo "$firstname $lastname"; ?></p>

Basically it works like this, but you have to check if the input is valid, i.e. it is not executable code like Javascript or PHP. Then the source can change, instead of the $_POST, initialized by the method of the form (<form method="post" ...), you can get the input from the database or from the session.

The same can be done in Python if you feel more confortable with it. You can also use Javascript, and use AJAX to save the input on the server side. To generate PDF files with Javascript you can try this:

But there are also server side solutions for PHP and Python.

These links may be useful for you:

cereal 1,524 Nearly a Senior Poster Featured Poster
cereal 1,524 Nearly a Senior Poster Featured Poster

You can save the datetime as UTC in the posts table, and then convert it to the user timezone, basing on his profile preferences. For example:

<?php

    $times  = DateTimeZone::listIdentifiers();
    $utc    = key(array_slice($times, -1, 1, TRUE));
    $getTZ  = array_key_exists('tz', $_GET) ? (int)$_GET['tz'] : $utc;

    # generate list of timezones
    $list = array();
    foreach($times as $key => $value)
    {
        if($key == $getTZ)
        {
            $list[] = "<option value=\"{$key}\" selected>$value</option>";
        }

        else
        {
            $list[] = "<option value=\"{$key}\">$value</option>";
        }
    }

    $dt     = new DateTime('now', new DateTimeZone($times[$utc]));
    $date   = $dt->format('Y-m-d G:i:s');

    $dt->setTimezone(new DateTimeZone($times[$getTZ]));
    $converted_date = $dt->format('Y-m-d G:i:s');

    echo "<p><strong>Default:</strong> UTC {$date}</p>";
    echo "<p><strong>Converted:</strong> {$times[$getTZ]} {$converted_date} </p>";


?>

<form method="get" action="">
    <select name="tz">
        <?php echo implode("\n", $list); ?>
    </select>
    <input type="submit" name="submit" value="update" />
</form>

This will generate this kind of output:

Default: UTC 2014-07-11 14:20:29
Converted: Pacific/Funafuti 2014-07-12 2:20:29

Now, when you retrieve the datetime column from the posts table use something like:

$times = DateTimeZone::listIdentifiers();
$userTZ = $_SESSION['user_timezone'];

$dt = new DateTime($row['date'], new DateTimeZone('UTC'));
$dt->setTimezone(new DateTimeZone($times[$userTZ]));
echo $dt->format('Y-m-d G:i:s');

In this example the timezone is set in the session, so when the user logs in. In order to work you can create a column timezone in the users table and save her/his preference. Use the array created by DateTimeZone::listIdentifiers() for this operation.

For more information check the documentation:

Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster
diafol commented: Thanks for the link to info on mysqlslap +14
cereal 1,524 Nearly a Senior Poster Featured Poster

Sorry for the late update, but I realized I wrote something very wrong in my last post. I wrote:

On line 31 you wrote:

if(crypt($_POST["curpassword"], $row["hash"]) != $row["hash"]))

You're using the hash as second argument of crypt, i.e. as salt, but this will always compare different unless $_POST["curpassword"] is blank. Correct version should be:

if(crypt($_POST["curpassword"]) != $row["hash"])

but the OP crypt() implementation is correct. I don't know what I was thinking, my excuses for the wrong information.

As example test:

$post = 'secret';
$salt = '$5$rounds=5000$yd792hcQbEOMHmfi$'; # sha256

# generate hash
$row = crypt($post, $salt);

# check hash
echo crypt($post, $row) == $row ? 'true' : 'false';

Will return true. Bye.

diafol commented: senior moment? heh heh - welcome to a very big club! +14
cereal 1,524 Nearly a Senior Poster Featured Poster

The salt is just an extra string used to change the output of the hash function, you can store this as a plain text string, or you can use an encrypt function like AES_ENCRYPT() in MySQL, example:

-- encrypt the salt
select HEX(AES_ENCRYPT('salt', 'encrypt key')) as encrypted_salt;
+----------------------------------+
| encrypted_salt                   |
+----------------------------------+
| CCBD9EDD8D878696FD44ED6720F7694E |
+----------------------------------+
1 row in set (0.12 sec)

-- decrypt the salt
select AES_DECRYPT(UNHEX('CCBD9EDD8D878696FD44ED6720F7694E'), 'encrypt key') as decrypted_salt;
+----------------+
| decrypted_salt |
+----------------+
| salt           |
+----------------+
1 row in set (0.00 sec)

Note that you need an encrypt/decrypt key as second argument of AES_ENCRYPT() and AES_DECRYPT(). The point is to limit damage if an hash is leaked at application level, for example: by using different salts you cannot see which users are using the same password. But if an attacker can submit arbitrary code, then you cannot do much.

For more information read these links:

cereal 1,524 Nearly a Senior Poster Featured Poster

If the condition doesn't match then redirect with an error message, for example:

<?php

session_start();

if($_POST['submit'])
{
    $db = /* connection to database */
    $stmt = $db->prepare("SELECT username FROM users WHERE username = ?");
    $stmt->execute(array($_POST['username']));
    $row = $stmt->fetch(PDO::FETCH_NUM);

    # if FALSE then the username does not exists
    if($row === false)
    {
        # continue the registration process
    }

    else
    {
        # redirect with error message
        $_SESSION['error'][] = 'Username already in use';
        header('Location: ' . $_SERVER['HTTP_REFERER']);
    }
}

And in your form page:

<?php
    # always on top of file
    session_start();

And below, in your page, you display the errors:

<?php
    if($_SESSION['error'])
    {
        foreach($_SESSION['error'] as $err)
        {
            echo "<p>{$err}</p>";
        }

        # unset error messages
        $_SESSION['error'] = null;
    }
?>

Then it's up to you when validate the other submitted data (before or after verifying the username), but you should never rely on javascript, even using AJAX: it can be disabled.

cereal 1,524 Nearly a Senior Poster Featured Poster

Sorry for the mistake, in my previous example I was referring to orders.id_customer, but nevermind: I exported the schema from the workbench file and I saw a date_add column in the orders table, so try this query:

SELECT customer.id_customer, customer.firstname, customer.lastname, orders.id_order, orders.date_add FROM customer, orders WHERE customer.id_customer = orders.id_customer GROUP BY orders.id_customer ORDER BY orders.date_add ASC;

Live example: http://sqlfiddle.com/#!2/17133/1

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, then remove customer.id_customer = ? and the limit clause, and try to use GROUP BY:

SELECT customer.id_customer, customer.firstname, customer.lastname, orders.id_order, order_history.date_add FROM customer, orders, order_history WHERE customer.id_customer = orders.id_customer AND orders.id_order = order_history.id_order GROUP BY order_history.id_customer ORDER BY order_history.date_add ASC;

It should return the correct rows.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, here you can see the database schema:

And you can also download the MySQL Workbench file. Maybe you can try something like this:

SELECT customer.id_customer, customer.firstname, customer.lastname, orders.id_order, order_history.date_add FROM customer, orders, order_history WHERE customer.id_customer = ? AND customer.id_customer = orders.id_customer AND orders.id_order = order_history.id_order ORDER BY order_history.date_add ASC LIMIT 1;

This should return the first order made by the customer, to get the last one use desc, instead of asc, in the order by clause.

Note: the question mark in the query should be replaced by the customer id number.

cereal 1,524 Nearly a Senior Poster Featured Poster

Place session_start() on top of this script otherwise $_SESSION won't be loaded and the IF statement will return false. Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

not working

Can you explain what and why it doesn't work? If you don't give us details, we cannot help much.

cereal 1,524 Nearly a Senior Poster Featured Poster

you might have to set GD2 to lowercase, not sure if that makes any difference?

Good suggestion, but no, the initialize() method uses strotolower() to rewrite the image_library value:

$this->image_library = strtolower($this->image_library);

A part that, it could be permissions, memory or other problems, like uploads size limits...

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, what does returns from:

echo $this->image_lib->display_errors();
cereal 1,524 Nearly a Senior Poster Featured Poster

@accra

A part Hiroshe's suggestion which I would strongly consider, to explain the pratical issue with your script, the problem is this:

$salt = uniqid(mt_rand()+microtime(true), true);
$password=hash('sha256',$password.$salt); // Encrypted password

Both in your registration and forget pages you are appending a $salt variable to the password. If you do this, then you have to save the salt value to the database, separated from the password, for example:

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `email` varchar(255) NOT NULL,
  `password` char(64) NOT NULL,
  `salt` varchar(50) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

At the moment in your login page you are not considering anymore the salt, which will change and if you don't save the original value created during the registration or recovery (forget page) process, then you cannot sign into the secure session.

So, when you verify the login, the query at line 16 of the login page becomes:

$query = "select * from users where email = '$email' and password = (sha2(concat('$password', salt), 256))";

Here we're using the sha2() function in MySQL which allows to use SHA-224, SHA-256, SHA-384, and SHA-512 hash functions. The first argument of sha2: is a concat() between the password in clear text and the salt column that matches with the searched email; the second argument is the hash value, which in this case is 256. So with a single query you can check if the user is allowed.

Note 1: uniquid() is …

cereal 1,524 Nearly a Senior Poster Featured Poster

On line 13 you're creating the hash without the salt:

$hashed = hash('sha256',$password);

So, it cannot generate the same hash, if you're going to use random salts for each user, then you must save it to the database.

Right now it probably works during registration & login because you create a cookie, and there's a check here:

if( isset($_SESSION['email']) || isset($_COOKIE['email'])) { // if session or cookie is stored
  header("Location: zalla/fbdashboard.php"); // redirect to home, no need to logged in
  exit();
}

that will redirect without matching the password.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, the query at line 18 is not correct because you're going to set 1 to the unfavorite column, no matter what is the value of $_REQUEST['favorite'].

Try to avoid $_REQUEST and use $_POST or $_GET, otherwise the script can receive input from different sources: cookies, post & get requests.

The IF statement at line 20 is not correct:

if(unfavorite="1" where id='".$id."')
{
    "delete from favoritedeals WHERE id= '".$id."'";
}

It seems SQL. Your intention is to delete the row?

Anyway, I would change your script a bit, you can use a single update query to set up the favorite and to remove it:

UPDATE favoritedeals SET favorite = CASE WHEN favorite = 0 THEN 1 ELSE 0 END WHERE id = $id

To do this, remove the unfavorite column, and change the favorite column to tinyint type, with default value 0: when the value is 0 the item is not between the favorites, when is 1 is a favorite. So, the example of the table is this:

create table favoritedeals(
id int unsigned not null auto_increment primary key,
favorite tinyint unsigned not null default 0
) engine = myisam;

Then change your script to this:

<?php

require_once('config.php');

# default message
$posts[0]['message'] = 'Error: specify favorite and/or a valid id.';

if(array_key_exists('id', $_REQUEST))
{
    $id     = (int)$_REQUEST['id'];
    $update = mysql_query("UPDATE favoritedeals SET favorite = CASE WHEN favorite = 0 THEN 1 ELSE 0 END WHERE id = $id");

    # overwrite the default message
    $posts[0]['message'] …
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, can you paste an output hash? For example, I tried this:

And it returns the same hash of md5() in PHP:

echo md5("hello"); // 5d41402abc4b2a76b9719d911017c592

But I don't know JAVA well, so my example could be wrong.

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, then try:

<?php

    # initialize the variable
    $code = '';

    # check if it exists and if it is alpha-numeric
    if(array_key_exists('code', $_GET) && ctype_alnum($_GET['code']) === true)
    {
        $code = $_GET['code'];
    }
?>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
    <div class="form-group">
        <input type="password" id="password" name="password" size="25"  class="form-control input-lg" placeholder="Enter Password">
    </div>

    <div class="form-group">
        <input type="password" id="passwordconfirm" name="passwordconfirm" size="25"  class="form-control input-lg" placeholder="Re-Enter Password">
    </div>

    <div class="form-group">
        <input type="submit" value="Reset Password" name="login" class="btn btn-default btn-lg btn-block" />
    </div>
    <?php
        # adding hidden input $_POST['code']
        echo "<input type=\"hidden\" name=\"code\" value=\"{$code}\" />";
    ?>
</form>

Then in your script check for $_POST['code']. Otherwise append it to the action url of the form and then, while receiving the input, search for $_GET['code']:

<?php

    # initialize the variable
    $action = htmlspecialchars($_SERVER['PHP_SELF']);

    # check if $_GET['code'] exists
    if(array_key_exists('code', $_GET) && ctype_alnum($_GET['code']) === true)
    {
        $action .= '?code='. $_GET['code'];
    }

?>
<form method="post" action="<?php echo $action; ?>">
    <div class="form-group">
        <input type="password" id="password" name="password" size="25"  class="form-control input-lg" placeholder="Enter Password">
    </div>

    <div class="form-group">
        <input type="password" id="passwordconfirm" name="passwordconfirm" size="25"  class="form-control input-lg" placeholder="Re-Enter Password">
    </div>

    <div class="form-group">
        <input type="submit" value="Reset Password" name="login" class="btn btn-default btn-lg btn-block" />
    </div>
</form>

Note that by using this last method, the first part of your script, i.e.:

if(!empty($_GET['code']) && isset($_GET['code']))
{
    # code

Will always run. To avoid it, add $_SERVER['REQUEST_METHOD'] == 'GET' to the statement:

if($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET['code']) && ! empty($_GET['code']))
cereal 1,524 Nearly a Senior Poster Featured Poster

Remove all the spaces at the left side of EOF; and then go to a new line, so remove also any spaces after EOF;, so:

<?php 
    require_once 'config.php'; 
    $title = "Home!";
    $content = <<<EOF
        <h3>Current Statistics</h3>   
        Our Home Page!      
EOF;
        include 'layout.php';
?>

From documentation:

The closing identifier must begin in the first column of the line.

And:

Warning
It is very important to note that the line with the closing identifier must contain no other characters, except a semicolon (;). That means especially that the identifier may not be indented, and there may not be any spaces or tabs before or after the semicolon. It's also important to realize that the first character before the closing identifier must be a newline as defined by the local operating system.

Source:

Bye :)

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, try to append the query string to the action of the form:

<form method="post" action="receiving.php?<?php echo $_SERVER['QUERY_STRING']; ?>">

Or use an hidden input field:

<input type="hidden" name="code" value="<?php echo $_SERVER['QUERY_STRING']; ?>" />

But in this last case, then check for $_POST['code'] instead of $_GET['code'].

Or, if you're using $_SESSION:

<?php

    session_start();
    $_SESSION['code'] = $_GET['code'];

be sure to start it also in the receiving script, and check for $_SESSION['code'] instead of $_GET['code']:

<?php

    session_start();

    if(array_key_exists('code', $_SESSION))
    {
        # code here ...

This:

$check_cod=mysql_real_escape_string($_GET['code']);
$check_code=$_SESSION['$check_cod'];

is wrong, for different reasons:

  1. single quotes will not process the variable, so you don't get the value but an index key literally named $check_cod;
  2. you probably don't want to use the variable value as index key of your session, otherwise an attacker could try to pull out some information about a user session, submitting arbitrary index keys.

If you have problems, please share the form you're using to update the password. Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, change your javascript to:

element1.name="chk[]";
element2.name="txt[]";
element3.name="qty[]";

that will generate this structure:

Array
(
    [chk] => Array
        (
            [0] => on
            [1] => on
            [2] => on
        )

    [txt] => Array
        (
            [0] => item 1
            [1] => item 2
            [2] => item 3
        )

    [qty] => Array
        (
            [0] => 17
            [1] => 34
            [2] => 23
        )

    [submit] => Submit
)

And it should work fine.

ms061210 commented: Thank you very much! It Works! +1
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, can you show the form?

Looking at the array output, it seems most of the values are under the index key txtbox while only the first is under txt which is the one you're trying to loop:

array(4)
{
    ["txt"]=> array(1)
    {
        [0]=> string(5) "item1"
    }

    ["qty"]=> array(1)
    {
        [0]=> string(1) "2"
    }

    ["txtbox"]=> array(4)
    {
        [0]=> string(5) "item2"
        [1]=> string(1) "3"
        [2]=> string(5) "item3"
        [3]=> string(1) "4"
    }

    ["submit"]=> string(6) "Submit"
}
cereal 1,524 Nearly a Senior Poster Featured Poster

Look at group_concat() in MySQL:

To create a query like this:

select s.name, group_concat(sa.artist order by sa.artist) as artists from songs s, songartists sa where s.id = sa.sid group by sa.sid;

But I would create an artists table, so you don't have to repeat the same artist each time you insert a new song, the new schema would look like this:

create table songs(
  id int unsigned not null auto_increment primary key,
  name varchar(50) not null,
  size int unsigned not null default 0,
  lyrics varchar(35) not null default '',
  music varchar(35) not null default '',
  mastered varchar(35) not null default '',
  link varchar(255) not null default '',
  added timestamp not null default current_timestamp
) engine = myisam;

create table artists(
  id int unsigned not null auto_increment primary key,
  name varchar(255) not null
) engine = myisam;

create table songartists(
  song_id int unsigned not null,
  artist_id int unsigned not null
) engine = myisam;

And the query would be:

select s.name, group_concat(a.name order by a.name) as artists from songs s, artists as a, songartists sa where s.id = sa.song_id and a.id = sa.artist_id group by sa.song_id;

Here there are two examples, the first is based on your two tables, the second on my suggested method:

Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

could you explain how the unique key definition works?

A unique index is like a primary key, in both cases it can be composed by a single column or by multiple columns: in the last case it works like a sorted array. For more information and examples check this:

cereal 1,524 Nearly a Senior Poster Featured Poster

The unique index works on the combination of all four columns, so it's the equivalent of the select query proposed by Ancient Dragon, if the key combination does not exists there will be an INSERT, else there will be an update. Check this live example:

Or I'm missing something?

showman13 commented: that is amazing - exactly what I was looking for. Thank You very much. +2
cereal 1,524 Nearly a Senior Poster Featured Poster

Otherwise use INSERT ... ON DUPLICATE KEY UPDATE, you have to create a unique key index:

ALTER TABLE tablename ADD UNIQUE KEY(pg_name,mem_id,ct_year,ct_month);

Then your insert query becomes:

INSERT INTO tablename (pg_name, mem_id, ct_year, ct_month, count) VALUES('page.html', 1, 2014, 7, 1) ON DUPLICATE KEY UPDATE count = count + 1;

Docs:

Bye! :)

cereal 1,524 Nearly a Senior Poster Featured Poster

Do you have write permissions on songs directory?

almostbob commented: I thought its an appropriate Q +13
cereal 1,524 Nearly a Senior Poster Featured Poster

Try by adding a backslash:

mv Abhishek\�_xyz.docx newname.docx

Or with double quotes:

mv "Abhishek�_xyz.docx" newname.docx

Or by using a wildcard:

mv Abhish* newname.docx

By the way which kind of shell are you using? Bash?

cereal 1,524 Nearly a Senior Poster Featured Poster

It's probably due to this:

If you are using MySQL 3.23 or later, you can copy the .frm, .MYI, and .MYD files for MyISAM tables between different architectures that support the same floating-point format.

And:

If you want to move applications to another machine having a different architecture or operating system than that of the current machine, you should not try to move a database by simply copying the files to the other machine. Use mysqldump instead.

Source: http://dev.mysql.com/doc/refman/4.1/en/copying-databases.html

So it depends on the CPU of these machines:

As suggested by the documentation use mysqldump and mysqlimport:

Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster
hallianonline commented: Thanks for your help +2
cereal 1,524 Nearly a Senior Poster Featured Poster

You're welcome and, please, mark the thread as solved. Bye! :)

cereal 1,524 Nearly a Senior Poster Featured Poster

why is it that i cant anymore upload file.

Hi, it can depend on many factors. How big are these files? The default file size limit for the uploads in PHP is 2MB. Check in your PHP configuration the values of post_max_size, upload_max_filesize and memory_limit:

You can access to this information reading the file php.ini or through phpinfo():

<?php

    phpinfo();

Also try to return the $_FILES array from the upload method, just place the return at the top of the method to output directly the array contents:

Route::post('/upload_file', function()
{
    return "<pre>".print_r($_FILES, true)."</pre>";

    # ... other code ...

}

If it works fine you get:

Array
(
    [upload] => Array
        (
            [name] => userguide.pdf
            [type] => application/pdf
            [tmp_name] => /tmp/phpW1NMHq
            [error] => 0
            [size] => 448075
        )

)

If you get an empty array, then you're probably hitting one of the above limits. And if you check the error log of your web server you will find the occurring error:

[Sat Jun 28 13:30:14 2014] [error] [client 127.0.0.1] PHP Warning:  POST Content-Length of 22982481 bytes exceeds the limit of 20971520 bytes in Unknown on line 0, referer: http://localhost/upload_form

Note: regarding my previous example the table name is not correct, I wrote docs_file instead of doc_files... so if you want to try be aware of this mistake.

cereal 1,524 Nearly a Senior Poster Featured Poster

Wait, how big are these files?

Also, try to download one of these files through a test script, for example:

<?php

# database credentials
$dbhost = 'localhost';
$dbname = 'dbname';
$dbuser = 'dbusername';
$dbpass = 'dbpassword';

try
{
    $db = new PDO("mysql:host={$dbhost};dbname={$dbname}", $dbuser, $dbpass);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}

catch(PDOException $e)
{
    echo "<p>".date('Y-m-d G:i:s') . " [ERROR]: " . $e->getMessage() . "</p>\n\r";
    $db = null;
}

$id = $_GET['id'];
$stmt = $db->prepare("SELECT * FROM docs_file WHERE docs_id = :id limit 1");
$stmt->execute(array(':id' => $id));

$row = $stmt->fetch(PDO::FETCH_ASSOC);

header('Content-type: '. $row['mimetype']);
header('Content-length: '. $row['size']);

echo $row['data'];

Save it as getfile.php in /public/ and then from the browser call:

http://localhost/getfile.php?id=1

If it still does not work, for example returns file corrupted, open the web developer console, it should open by pressing CTRL + SHIFT + J in Google Chrome, select the Network tab and reload the link, it will appear something like this:

getfile.php?id=1

right click on it and select Copy Response Headers, you should get something like this:

HTTP/1.1 200 OK
Date: Fri, 27 Jun 2014 15:47:27 GMT
Server: Apache
Content-Length: 334549
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/pdf

A better tool to debug these kind of scripts is httpie, if you want to try:

Or Postman, an extension for Google Chrome:

Both will return also the body response and if there is an error in the code, you will see it, for example:

Notice: Undefined index: data …
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, let me understand: do you want an autocomplete function over an input text field? Or a select dropdown? Also, can you show the form?

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, can you show some example data and the table structure?

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, the variable $data is used for the binary data not for the file name, so change the line 4:

$data = $file[0]->filename;

to:

$data = $file[0]->data;

And it should work fine.

cereal 1,524 Nearly a Senior Poster Featured Poster

what 200 stands for on the get file function.

200 is the HTTP status used for successful HTTP requests, for more information check:

I suppose there is some broken data in your table, because of the previouses tests. Could you truncate the table and start some new uploads? Use:

truncate table docs;

This will delete all the previous rows. If, after doing this operation, it doesn't work, please share your updated and working code, related to your updated database table.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

to be sure ask to the hosting support, regarding OpenShift check this link:

it seems you can get the listening IP by echoing few system variables:

  • OPENSHIFT_<cartridge>_IP
  • OPENSHIFT_<cartridge>_PORT

In practice from ssh run commands like these:

echo $OPENSHIFT_APPNAME_IP
echo $OPENSHIFT_APPNAME_PORT

Source:

cereal 1,524 Nearly a Senior Poster Featured Poster

If you use:

$config['sess_encrypt_cookie']  = TRUE;
$config['sess_use_database']    = TRUE;

And create a session table:

CREATE TABLE IF NOT EXISTS  `ci_sessions` (
    session_id varchar(40) DEFAULT '0' NOT NULL,
    ip_address varchar(45) DEFAULT '0' NOT NULL,
    user_agent varchar(120) NOT NULL,
    last_activity int(10) unsigned DEFAULT 0 NOT NULL,
    user_data text NOT NULL,
    PRIMARY KEY (session_id),
    KEY `last_activity_idx` (`last_activity`)
);

The session cookie will store only this information:

  • session_id
  • ip_address
  • user_agent
  • last_activity

And the cookie will be encrypted with mcrypt, up to version 2.1.4 if mcrypt was not available then they used the _xor_encode() method:

function encode($string, $key = '')
{
    $key = $this->get_key($key);

    if ($this->_mcrypt_exists === TRUE)
    {
        $enc = $this->mcrypt_encode($string, $key);
    }
    else
    {
        $enc = $this->_xor_encode($string, $key);
    }

    return base64_encode($enc);
}

In version 2.2.0 the _xor_encode() method was removed and the encode method now works like this:

function encode($string, $key = '')
{
    $key = $this->get_key($key);
    $enc = $this->mcrypt_encode($string, $key);

    return base64_encode($enc);
}

and in constructor they check if mcrypt is available:

public function __construct()
{
    $this->CI =& get_instance();
    $this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;

    if ($this->_mcrypt_exists === FALSE)
    {
        show_error('The Encrypt library requires the Mcrypt extension.');
    }

    log_message('debug', "Encrypt Class Initialized");
}

If not the Encrypt class won't start.

Ref:

Custom data, instead, will be saved in ci_sessions.user_data. So you never reach the 4KB limit for the session cookie and you can save more data.

Now, having mcrypt enabled is sufficient, but …

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, check /app/config/app.php to be sure that debug is set to true then, if this is still your table structure:

CREATE TABLE docs (
    gov_docs_id int(11) NOT NULL AUTO_INCREMENT,
    personnel_id int(11) DEFAULT NULL,
    docs_name varchar(255) DEFAULT NULL,
    docs_num int(11) DEFAULT NULL,
    docs_date datetime DEFAULT NULL,
    filename varchar(255) DEFAULT NULL,
    data longblob,
    PRIMARY KEY (gov_docs_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Change it, to add the columns size and mime, just run these commands in a MySQL client:

alter table docs add size int unsigned not null default 0;
alter table docs add mime varchar(255) not null;

Then change your code to:

Route::get('/getfile/{id}', function($id)
{
    $file = DB::select('SELECT * FROM docs WHERE gov_docs_id = ?', array($id));
    $data = $file[0]->file;
    return Response::make($data, 200, array('Content-type' => $file[0]->mime, 'Content-length' => $file[0]->size));
});

In order to work fine you have to change also the script used to save the file to the database and add the mine and size columns:

$mime = Input::file('upload')->getMimeType();
$size = Input::file('upload')->getSize();

DB::table('docs')->insert(array(
    'doc_attachment'=> $data,
    'mime' => $mime,
    'size' => $size
    )
);

Remember to change tablename to your current table name (i.e. docs), and also refer to the correct id, which in your table is gov_docs_id. If the problem persists check che error log in /app/storage/logs/ and Apache error log.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, what kind of error you get?

cereal 1,524 Nearly a Senior Poster Featured Poster

Line 36:

<?}?>

change it to:

<?php } ?>

Or to:

<? } ?>

In practice provide some space.

cereal 1,524 Nearly a Senior Poster Featured Poster
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, remove the curly bracket } at line 8.

cereal 1,524 Nearly a Senior Poster Featured Poster

Sorry, I was referring to CI, in reply to:

It seems it is fixed in 3.0 but I know that version isn't stable.

EllisLab made this upgrade to fix the session cookie vulnerability discussed in your link. About 2.2.0:

CodeIgniter 2.2.0 has been released today, and is a security release for the 2.x branch. One of these changes is significant, so please be sure to read the version notes for upgrading from 2.1.4 to 2.2.0 to ensure your environment is ready for the update.

Just make sure to have mcrypt enabled and then upgrade from 2.1.4 to 2.2.0, which includes also few minor bug fixes:

cereal 1,524 Nearly a Senior Poster Featured Poster

The error:

Fatal error: Call to a member function query() on a non-object in index.php on line 25

Is a consequence of:

SQLSTATE[HY000] [1045] Access denied for user 'demo'@'localhost' (using password: YES)

And as in my previous post:

Use the correct credentials (user and password) to access the database...

Which means that username or password for your database are wrong. Does user demo exists in your database? It has privileges to access the database named try?

cereal 1,524 Nearly a Senior Poster Featured Poster

Version 2.2.0, released few days ago, fixes this bug. Bye!