Connecting To Mongo Replica Set With Doctrine MongoODM Module - php

We are in the process of updating our API's MongoDB hosting provider from mLab to MongoDB Atlas.
I have updated our connection server to PHP 7.4 with MongoDB PHP extension 1.7.4.
I have updated our API framework from Apigility to Laminas API Tools using the DoctrineMongoODMModule
I can successfully connect using the mongo shell using the following syntax:
mongo "mongodb+srv://test-server-dbteb.mongodb.net/<dbname>" --username <username>
I have looked far and wide to find a sample configuration of the DoctrineMongoODMModule with it's configuration file to connect to a MongoDB Atlas replica set using the mongo+srv:// protocol with no success to this point. Currently the errors are Failed to parse MongoDB URI.
If anyone has had a similar experience, any help would be greatly appreciated.

I had the same issue and im still looking forward to get a real solution.
I directly edited the ConnectionFactory.php in the doctrine-mongo-odm-module (src/DoctrineMongoODMModule/Service/ConnectionFactory.php) with the following code
//...
if (empty($connectionString)) {
$connectionString = 'mongodb+srv://'; //prev: 'mongodb://'
$user = $options->getUser();
$password = $options->getPassword();
$dbName = $options->getDbName();
if ($user && $password) {
$connectionString .= $user . ':' . $password . '#';
}
$connectionString .= $options->getServer() /*. ':' . $options->getPort()*/;
if ($dbName) {
$connectionString .= '/' . $dbName;
}
} else {
// parse dbName from the connectionString
$dbStart = strpos($connectionString, '/', 11);
if ($dbStart !== false) {
$dbEnd = strpos($connectionString, '?');
$dbName = substr(
$connectionString,
$dbStart + 1,
$dbEnd ? ($dbEnd - $dbStart - 1) : PHP_INT_MAX
);
}
}
//...
and in my connection file:
//...
'odm_default' => array(
'server' => '<host>',
'port' => '',
'connectionString' => null,
'user' => '<user>',
'password' => '<psw>',
'dbname' => '<db>',
'options' => array()
),
//...
I think this is the worst possible solution (editing vendor' files) but in my case worked, take that as a temporary fix

Related

F3 Framework: how to make sure that caching is working correctly?

I'm getting the database credentials from AWS secrets manager and storing it in the cache so that it doesn't have to be fetched from AWS on every request.
The problem is that, if I change the secret name for testing, F3 won't be able to connect to the database. That means that it's detecting the secret name getting changed even though I tell F3 to check that only if it wasn't able to find anything cached.
use Aws\SecretsManager\SecretsManagerClient;
$f3->set('CACHE', true);
if ($f3->exists('dbusername')) {
$username = $f3->get('dbusername');
$password = $f3->get('dbpassword');
$host = $f3->get('dbhost');
$port = $f3->get('dbport');
} else {
$secretName = getenv('AWS_SECRET_NAME');
$client = new SecretsManagerClient([
'version' => 'latest'
]);
$secretManager = $client->getSecretValue([
'SecretId' => $secretName,
]);
$db = json_decode($secretManager['SecretString']);
$username = $db->username;
$password = $db->password;
$port = $db->port;
$host = $db->host;
}
$f3->set('dbusername', $username);
$f3->set('dbpassword', $password);
$f3->set('dbhost', $host);
$f3->set('dbport', $port);
I'm testing on my PC, I don't know if that code would work on a server, not sure if the issue from my PC or if I'm not caching correctly.
It turns out that the cache wouldn't work unless a ttl (time to live) is specified. Here's how to cache the values above for 24 hours.
$f3->set('dbusername', $username, 86400);
$f3->set('dbpassword', $password, 86400);
$f3->set('dbhost', $host, 86400);
$f3->set('dbport', $port, 86400);

How to send commands using SOAP to AzerothCore worldserver console?

How can I run a command after enabling SOAP to AzerothCore worldserver console?
First of all, you have to put on worldserver.conf these parameters to enable SOAP:
SOAP.Enabled = 1
SOAP.IP = "127.0.0.1"
SOAP.Port = 7878
Afterwards, run your worldserver.
You can use a simple PHP script to run a command to the AzerothCore console like the following,
If you don't have php-soap, on Linux Ubuntu you can install it using sudo apt install php-soap (or php7.2-soap).
<?php
$soap_connection_info = array(
'soap_uri' => 'urn:AC',
'soap_host' => '127.0.0.1',
'soap_port' => '7878',
'account_name' => 'USERNAME',
'account_password' => 'PASSWORD'
);
function RemoteCommandWithSOAP($username, $password, $COMMAND)
{
global $soap_connection_info;
$result = '';
try {
$conn = new SoapClient(NULL, array(
'location' => 'http://' . $soap_connection_info['soap_host'] . ':' . $soap_connection_info['soap_port'] . '/',
'uri' => $soap_connection_info['soap_uri'],
'style' => SOAP_RPC,
'login' => $username,
'password' => $password
));
$result = $conn->executeCommand(new SoapParam($COMMAND, 'command'));
unset($conn);
} catch (Exception $e) {
$result = "Have error on soap!\n";
if (strpos($e, 'There is no such command') !== false) {
$result = 'There is no such command!';
}
}
return $result;
}
echo RemoteCommandWithSOAP($soap_connection_info['account_name'], $soap_connection_info['account_password'], ".server info");
?>
In the last line you have to change "account_name", "account_password" using an account with gm level 3.
echo RemoteCommandWithSOAP($soap_connection_info['account_name'], $soap_connection_info['account_password'], ".server info");
You can replace .server info with any command.
Note: this works with other emulators just replacing urn:AC with:
- urn:MaNGOS for CMaNGOS (and related forks)
- urn:TC for TrinityCore
- urn:SF for SkyfireProject
- urn:Oregon for OregonCore
etc...
Here is a perl script to do the same thing, it requires libsoap-lite-perl, install with apt-get install libsoap-lite-perl
Put the code below in a file named soap.pl:
#!/usr/bin/perl
use strict;
use warnings;
use SOAP::Lite; # visit http://search.cpan.org/dist/SOAP-Lite/ or apt-get install libsoap-lite-perl
my ($user, $pass) = ('gm_account', '1234');
my $host = 'http://127.0.0.1:7878/';
my $cmd = '.server info';
BEGIN {
sub SOAP::Transport::HTTP::Client::get_basic_credentials {
return $user => $pass,
}
}
my $soap = SOAP::Lite
->proxy($host)
->uri('urn:AC');
my $rc = $soap->call('executeCommand',
SOAP::Data->name('command')->value($cmd));
die $rc->faultstring if ($rc->fault);
print
$rc->result;
Then start your worldserver and run like that perl soap.pl.
It should return the result of the command ".server info"

Connecting to web service using SOAP & PHP

I'm trying to connect to a web service using PHP's soap client which I can successfully do using Visual Studio, pressing F5 and running the page locally which works a treat.
As soon as I upload the exact same file to my apache web host, I keep getting the error: "failed to load external entity".
Here's my code with the credentials and url taken out...
Any ideas?
<?php
header("Access-Control-Allow-Origin: http://example.com");
header("Access-Control-Request-Method: GET,POST");
ini_set('display_errors', true);
ini_set("soap.wsdl_cache_enabled", "0");
error_reporting(E_ALL);
try
{
$soapclient = new SoapClient('http://example.com');
$params = array ('SystemID' => 'testID','Username' => 'test', 'Password' => 'test');
$response = $soapclient->GetEngineerList($params);
print_r($response);
}
catch(SoapFault $e)
{
print_r($e);
}
strings are not read twice and parsed in single quotes
$soapclient = new SoapClient('$url');
try
$soapclient = new SoapClient($url);
also...do you have $url = ''; anywhere?
UPDATE 1
please try using basic auth to get to your wsdl:
$login = 'bert';
$password = 'berts password';
$client = new SoapClient(
'http://' . urlencode($login) . ':' . urlencode($password) . '#www.server.com/path/to/wsdl',
array(
'login' => $login,
'password' => $password
)
);

Php pdo unixOBDC to sqlserver 2008: String data, length mismatch when execute prepared stmt

I have the following setup: Apache / php 5.3 / pdo with odbc with installed Microsoft SQL Server ODBC Driver 1.0 for Linux on server.
My script rises an error with the following stacktrace when trying to execute a statement:
(UTC) 2013-12-16 12:07:40: Thrown exception log ->
'Error message: SQLSTATE[22026]: String data, length mismatch: 0 [Microsoft][SQL Server Native Client 11.0]String data, length mismatch (SQLExecute[0] at /tmp/pear/temp/PDO_ODBC/odbc_stmt.c:133)
Arisen in Core_Db->select(array (
0 =>
'SELECT *
FROM TMS.dbo.TEST_user
WHERE email = ? AND status_id = ?',
1 =>
array (
0 => 'support#mail.com',
1 => 2
),
))
For testing I use php 5.3 on windows with pdo sqlsrv and nothing went wrong there.
Connection code is
// for unixODBC (production)
if (DB_DRIVER == 'odbc') {
$this->_link = new PDO(
"odbc:DRIVER={SQL Server Native Client 11.0};SERVER=" . DB_HOST . ";"
. "PORT=" . DB_PORT . ";DATABASE=" . DB_NAME . ";PROTOCOL=TCPIP;UID=" . DB_LOGIN . ";"
. "PWD=" . DB_PASSWD . ";"
);
// for sqlsrv (development)
} else {
$this->_link = new PDO(
"sqlsrv:Server=" . DB_HOST . "," . DB_PORT . ";Database=" . DB_NAME,
DB_LOGIN,
DB_PASSWD
);
}
$this->_link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
There is some recommendation regarding this issue: ODBC and SQL Server 2008: Can't use prepared statements?. But I can't check it. When I try to add an attribute in production, the script rises the following error:
(UTC) 2013-12-16 13:19:44: SQLSTATE[IM001]: Driver does not support this function: driver does not support setting attributes
Does anyone know how to resolve this problem?
UPDATED 2013-12-18
// unixODBC connection
$this->_link = new PDO(
"odbc:DRIVER={SQL Server Native Client 11.0};SERVER=xxx.xxx.xxx.xxx;"
. "PORT=1433;DATABASE=TMS;PROTOCOL=TCPIP;",
DB_LOGIN,
DB_PASSWD,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // this attr is recognized by ODBC
PDO::ATTR_EMULATE_PREPARES => false // but if this is added ODBC throws PDOException with message "driver does not support setting attributes"
)
);
String's transfer from ODBC to Client leads to string's corruption while prepared statement is used. So I only guess the matter is in PDO::ATTR_EMULATE_PREPARES.
The error
(UTC) 2013-12-16 13:19:44: SQLSTATE[IM001]: Driver does not support
this function: driver does not support setting attributes
is telling you that this line:
$this->_link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
is invalid. Instead, do this:
$driver_options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => FALSE);
if (DB_DRIVER == 'odbc'){ // for unixODBC (production)
$dsn = 'odbc:DRIVER={SQL Server Native Client 11.0};SERVER='. DB_HOST .';PORT='. DB_PORT .';DATABASE='. DB_NAME .';PROTOCOL=TCPIP;';
$this->_link = new PDO($dsn, DB_LOGIN, DB_PASSWD, $driver_options);
}else{ // for sqlsrv (development)
$this->_link = new PDO(
"sqlsrv:Server=" . DB_HOST . "," . DB_PORT . ";Database=" . DB_NAME,
DB_LOGIN,
DB_PASSWD
);
}

Read gmail with Zend Framework

Im trying to read mails from a gmail apps account by using Zend Framework. I've just transfered the Zend Framework dir to my server (path: /Zend/library/).
How do I load the Zend Framework and the Mail module? And how do I further read the mail?
I've tried the following with no results:
$path = 'Zend/library/';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
I believe the syntax for reading the inbox is something like:
$mail = new Zend_Mail_Storage_Imap(array('host' => 'imap.gmail.com', 'user' => "name#domain.com", 'password' => "mypassword", 'ssl' => 'SSL'));
EDIT
The following code works:
$path = 'Zend/library/';
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance();
$mail = new Zend_Mail_Storage_Imap(array('host' => 'imap.gmail.com',
'user' => 'mail#domain.com',
'password' => 'password',
'ssl' => 'SSL'));
echo $mail->countMessages();`
... but when i try to echo unread emails:
echo "Unread mails:\n";
foreach ($mail as $message) {
if ($message->hasFlag(Zend_Mail_Storage::FLAG_SEEN)) {
continue;
}
// mark recent/new mails
if ($message->hasFlag(Zend_Mail_Storage::FLAG_RECENT)) {
echo '! ';
} else {
echo ' ';
}
echo $message->subject . "\n";
}
I get the following message:
Fatal error: Uncaught exception 'Zend_Mail_Storage_Exception' with message 'cannot login, user or password wrong' in /var/www/zvinx.dk/test/Zend/library/Zend/Mail/Storage/Imap.php:279 Stack trace: #0 /var/www/zvinx.dk/test/gmail.php(11): Zend_Mail_Storage_Imap->__construct(Array) #1 {main} thrown in /var/www/zvinx.dk/test/Zend/library/Zend/Mail/Storage/Imap.php on line 279
It says the username or password is wrong, which is weird cause I didnt change it from when it was working... How come this error occur?
the gmail settings are a little tricky. try:
$mail = new Zend_Mail_Storage_Imap(array('host' => 'imap.gmail.com',
'user' => 'mail#domain.com',
'port' => '993',
'password' => 'password',
'ssl' => 'tls',
'auth' => 'login'
));
NOTE: the gmail are using the SSL/TLS protocol which apparently is different than the standard SSL.
You really don't think that you can start using Zend Framework without reading/learning about the basics of the framework? At least take a look at the quickstart on how to use the framework with the autoloading features and then dive into the Zend_Mail documentation, more specifically the part that says "Reading Mail Messages"
There are the login setting i use to read emails via IMAP and dump attached files
public function imapAction()
{
$config = array('host'=> 'imap.gmail.com',
'user' => 'xx',
'password' => 'xx',
'ssl' => 'SSL',
'port' => 993);//995 pop, imap 993
$mail = new Zend_Mail_Storage_Imap($config);
$maxMessage = $mail->countMessages();
$this->logger->info($maxMessage);
for ($i = $maxMessage; $i <= $maxMessage; $i++)
{
$message = $mail->getMessage($i);
$this->logger->info($i.'Mail from '.$message->from.':'.$message->subject);
if($message->isMultipart())
{
$this->logger->info("has attachments");
$part = $message->getPart(2);
$cnt_typ = explode(";" , $part->contentType);
$name = explode("=",$cnt_typ[1]);
$filename = $name[1];//It is the file name of the attachement in browser
//This for avoiding " from the file name when sent from yahoomail
$filename = str_replace('"'," ",$filename);
$this->logger->info($filename);
$attachment = base64_decode($part->getContent());
$fhandle = fopen($filename, 'w');
fwrite($fhandle, $attachment);
fclose($fhandle);
}
}
}
I had the same issue and this instruction has helped me.
Quit all mail clients that are accessing the affected Gmail account. This means the Mail app on the iPhone and any other place you are accessing your Gmail from such as a computer.
Open browser and navigate to this page: http://www.google.com/accounts/DisplayUnlockCaptcha
Enter your full Gmail address, password and type the characters you see in the picture. Touch the unlock button to verify your account.
Try to read mails from a gmail apps account by using Zend Framework. Your Gmail access should be restored.
If you encounter this error and you are 100% sure about the password you provided it might come from the 2 factor authentication you set on your google account.
Google help gives indications on what to do in this case. I manage to get access to my account by generating an AppPassword in my case

Categories